Setup

Clean directory and load packages

Helper function for converting a list of sillyvec on clipboard to separated by “;” for OceanAK lookup and pasted back to clipboard

sillyvec
 [1] "PAFK94H"   "PAFK14"    "PAFK91H"   "PAFK13"    "PCANN14"   "PCANN91H"  "PCANN15"   "PVFDA94H"  "PVFDA14"   "PVFDE91H"  "PVFDA15"   "PDUCK94T" 
[13] "PDUCK14E"  "PDUCK14L"  "PERBE91T"  "PERBL91T"  "PERB17"    "PGREG94"   "PGREG14E"  "PGREG14L"  "PGREG93U"  "PSIWAS15"  "PSPRING14" "PSPRING15"

Objective

The objective of this notebooks is to create an extraction list for our collaborative PWS Pink Salmon whole genome re-sequencing (WGR) project with the Christie Lab at Purdue University. The study design for this extraction list comes from:

V:\Documents\5_Coastwide\Multispecies\AHRP\Pink Salmon Disaster Funding\Round2\Objective 11 PWS WGR\Sample Units.xlsx
Sheet 2

Background

This project is using leftover Pink Salmon Disaster 2016 funds to try to address questions about potential genetic mechanisms causing reduced RRS. This project is broken into two main questions:

Sample Units

Screenshot of sample design

Screenshot of sample design

Using “output/PWS Pink Salmon WGR Extraction List.xlsx” and “output/extraction_selection.xlsx” to hand-pick most extractions

Updating to replace Gregorieff Creek 1993 and Siwash Creek 2015 as the VFDA brood source collections for the odd-lineage

Replacing with Duck River 191 and 2013. Duck River was not the brood source for VFDA, but it is the closest stream distance-wise. Gregorieff 1993 only had 16 alevin samples and Siwash 2015 did not have paired otolith data (so probably a bunch of strays mixed in).

Duck River 2014 + Gregorieff Creek 2014

Need the tissue information from LOKI tissue table Need the sex data from LOKI fish table Need the otolith data from warehouse

Pick fish and format for extraction (use PWS Pink as a template)

Import Data

LOKI Tissue Table

DWP information and tissue missing data lives here…

(loki_tissue_og <- readr::read_csv(file = "../data/LOKI_tissue_GEN_SAMPLED_FISH_TISSUE.csv"))
Warning: One or more parsing issues, see `problems()` for details
Rows: 19639 Columns: 32
-- Column specification -------------------------------------------------------------------------------------------------------------
Delimiter: ","
chr  (11): Silly Code, PK_TISSUE_TYPE, CAPTURE_LOCATION, DNA_TRAY_CODE, DNA_TRAY_WELL_POS, STORAGE_ID, UNIT, SLOT, EXHAUSTED_HOW,...
dbl   (9): FK_COLLECTION_ID, FK_FISH_ID, LATITUDE, LONGITUDE, CONTAINER_ARRAY_TYPE_ID, DNA_TRAY_WORKBENCH_ID, DNA_TRAY_WELL_CODE,...
lgl   (9): MESH_SIZE, MESH_SIZE_COMMENT, IS_MISSING_PAIRED_DATA_EXISTS, WELL_HAS_MORE_THAN_ONE_SAMPLE, IS_PRESENT_IN_DATASHEET, I...
date  (3): CAPTURE_DATE, END_CAPTURE_DATE, EXHAUSTED_DATE

i Use `spec()` to retrieve the full column specification for this data.
i Specify the column types or set `show_col_types = FALSE` to quiet this message.

Modify, filter for silly codes of interest and remove any fish with knwon missing tissues

(
  loki_tissue <- loki_tissue_og %>%
    dplyr::filter(
      `Silly Code` %in% c("PDUCK14E", "PDUCK14L", "PGREG14E", "PGREG14L"),
      PK_TISSUE_TYPE == "Heart",
      is.na(IS_MISSING_PAIRED_DATA_EXISTS),
      is.na(WELL_HAS_MORE_THAN_ONE_SAMPLE)
    ) %>%
    dplyr::rename(
      silly = `Silly Code`,
      fish_id = FK_FISH_ID,
      tissue_type = PK_TISSUE_TYPE,
      dwp_barcode = DNA_TRAY_CODE,
      dwp_well = DNA_TRAY_WELL_CODE
    ) %>%
    tidyr::unite(
      col = "silly_source",
      c(silly, fish_id),
      sep = "_",
      remove = FALSE
    ) %>%
    dplyr::select(
      silly,
      fish_id,
      silly_source,
      tissue_type,
      dwp_barcode,
      dwp_well
    )
)

LOKI Fish Table

Sex data lives here…

(loki_fish_og <- readr::read_csv(file = "../data/LOKI_fish_ASL Import.csv"))
Rows: 16927 Columns: 11
-- Column specification -------------------------------------------------------------------------------------------------------------
Delimiter: ","
chr (2): Silly Code, Sex
dbl (6): Collection ID, Fish ID, Freshwater Age, Ocean Age, Scale Card Number, Scale Card Position
lgl (3): Length, Weight, ASL Number

i Use `spec()` to retrieve the full column specification for this data.
i Specify the column types or set `show_col_types = FALSE` to quiet this message.

Modify, filter for silly codes of interest

(
  loki_fish <- loki_fish_og %>%
    dplyr::filter(
      `Silly Code` %in% c("PDUCK14E", "PDUCK14L", "PGREG14E", "PGREG14L")
    ) %>%
    dplyr::rename(
      silly = `Silly Code`,
      fish_id = `Fish ID`,
      sex = Sex
    ) %>%
    tidyr::unite(
      col = "silly_source",
      c(silly, fish_id),
      sep = "_",
      remove = TRUE
    ) %>%
    dplyr::select(silly_source, sex)
)

Salmon Biological Data

Otolith read data lives here…

(oceanak_og <- readr::read_csv(file = "../data/Duck 2014 and Gregorieff 2014 AHRP Salmon Biological Data 20220318_160209.csv"))
Rows: 1099 Columns: 22
-- Column specification -------------------------------------------------------------------------------------------------------------
Delimiter: ","
chr  (6): SILLY_CODE, TISSUE_TYPE, LOCATION_CODE, OTOLITH_MARK_PRESENT, OTOLITH_MARK_ID, OTOLITH_MARK_STATUS_CODE
dbl  (8): COLLECTION_ID, FISH_ID, DNA_TRAY_CODE, DNA_TRAY_WELL_CODE, SAMPLE_ID, SAMPLE_YEAR, IS_MISSING_PAIRED_DATA_EXISTS, WELL_...
lgl  (7): SEX, LENGTH_MM, TARGET_DNA_TRAY_CODE, TARGET_DNA_TRAY_WELL_POS, TARGET_CONTAINER_ARRAY_TYPE_ID, CONTAINER_ARRAY_TYPE, D...
dttm (1): SAMPLE_DATE

i Use `spec()` to retrieve the full column specification for this data.
i Specify the column types or set `show_col_types = FALSE` to quiet this message.

Modify, filter for silly codes of interest and tissue type “Otolith”

Join

Join all three of these data sources into something useful, then filter by our collections (Duck and Gregorioff 2014), non-missing tissue, natural-origin, split evenly across silly codes and sexes.

(join_duck_greg <- loki_tissue %>% 
   left_join(loki_fish, by = "silly_source") %>% 
   left_join(oceanak, by = "silly_source")
)

Extraction Selection

From each silly, grab the first 9 fish from each sex that are not otolith marked (i.e. natural-origin fish). Total of 18 fish per silly, 36 fish per sampling unit (early and late are still one sampling unit).

(
  extraction_duck_greg <- join_duck_greg %>%
    dplyr::filter(otolith_mark_present == "NO",
                  sex != "U") %>%
    dplyr::group_by(silly, sex) %>%
    dplyr::slice_min(order_by = fish_id, n = 9) %>%
    dplyr::ungroup() %>% 
    dplyr::arrange(silly, fish_id) %>% 
    dplyr::select(
      silly_source,
      silly,
      fish_id,
      dwp_barcode,
      dwp_well,
      tissue_type,
      sex,
      otolith_mark_present
    )
)

Write it out for posterity

readr::write_csv(x = extraction_duck_greg, file = "../output/extraction_selection_PDUCK14E_PDUCK14L_PGREG14E_PGREG14L.csv")

Erb 1991

Import Data

LOKI Tissue Table

DWP information and tissue missing data lives here…

(loki_tissue_og <- readr::read_csv(file = "../data/LOKI_tissue_GEN_SAMPLED_FISH_TISSUE.csv"))
Warning: One or more parsing issues, see `problems()` for details
Rows: 19639 Columns: 32
-- Column specification -------------------------------------------------------------------------------------------------------------
Delimiter: ","
chr  (11): Silly Code, PK_TISSUE_TYPE, CAPTURE_LOCATION, DNA_TRAY_CODE, DNA_TRAY_WELL_POS, STORAGE_ID, UNIT, SLOT, EXHAUSTED_HOW,...
dbl   (9): FK_COLLECTION_ID, FK_FISH_ID, LATITUDE, LONGITUDE, CONTAINER_ARRAY_TYPE_ID, DNA_TRAY_WORKBENCH_ID, DNA_TRAY_WELL_CODE,...
lgl   (9): MESH_SIZE, MESH_SIZE_COMMENT, IS_MISSING_PAIRED_DATA_EXISTS, WELL_HAS_MORE_THAN_ONE_SAMPLE, IS_PRESENT_IN_DATASHEET, I...
date  (3): CAPTURE_DATE, END_CAPTURE_DATE, EXHAUSTED_DATE

i Use `spec()` to retrieve the full column specification for this data.
i Specify the column types or set `show_col_types = FALSE` to quiet this message.

Modify, filter for silly codes of interest and remove any fish with knwon missing tissues

(
  loki_tissue <- loki_tissue_og %>%
    dplyr::filter(
      `Silly Code` %in% c("PERBE91T", "PERBL91T"),
      PK_TISSUE_TYPE == "Heart",
      is.na(IS_MISSING_PAIRED_DATA_EXISTS),
      is.na(WELL_HAS_MORE_THAN_ONE_SAMPLE)
    ) %>%
    dplyr::rename(
      silly = `Silly Code`,
      fish_id = FK_FISH_ID,
      tissue_type = PK_TISSUE_TYPE,
      dwp_barcode = DNA_TRAY_CODE,
      dwp_well = DNA_TRAY_WELL_CODE
    ) %>%
    tidyr::unite(
      col = "silly_source",
      c(silly, fish_id),
      sep = "_",
      remove = FALSE
    ) %>%
    dplyr::select(
      silly,
      fish_id,
      silly_source,
      tissue_type,
      dwp_barcode,
      dwp_well
    )
)

Wait, what? No tissues for PERBL91T….

Cool, no known missing, grab first 36 from PERBE91T until we figure out PERBL91T.

Erb 2017

Need the tissue information from LOKI tissue table Need the sex and otolith data from warehouse

Pick fish and format for extraction (use PWS Pink as a template)

Import Data

LOKI Tissue Table

DWP information and tissue missing data lives here…

(loki_tissue_og <- readr::read_csv(file = "../data/LOKI_tissue_GEN_SAMPLED_FISH_TISSUE_PERB17_20220321_150821.csv"))
Warning: One or more parsing issues, see `problems()` for details
Rows: 14955 Columns: 47
-- Column specification -------------------------------------------------------------------------------------------------------------
Delimiter: ","
chr  (14): SILLY_CODE, PK_TISSUE_TYPE, CAPTURE_LOCATION, STORAGE_ID, UNIT, DNA_TRAY_CODE, DNA_TRAY_WELL_POS, REGION_CODE, QUADRAN...
dbl  (14): FK_COLLECTION_ID, FK_FISH_ID, SHELF_RACK, SLOT, LATITUDE, LONGITUDE, DNA_TRAY_WELL_CODE, IS_MISSING_PAIRED_DATA_EXISTS...
lgl  (17): VIAL_BARCODE, EXHAUSTED_HOW, EXHAUSTED_BY, EXHAUSTED_DATE, MESH_SIZE, MESH_SIZE_COMMENT, AGENCY, COLLECTION_DATE, OTHE...
dttm  (2): CAPTURE_DATE, END_CAPTURE_DATE

i Use `spec()` to retrieve the full column specification for this data.
i Specify the column types or set `show_col_types = FALSE` to quiet this message.

Modify, filter for silly codes of interest and remove any fish with known missing tissues

erb_2017_oto_fish_ids <-
  dplyr::filter(.data = loki_tissue_og, PK_TISSUE_TYPE == "Otolith") %>% pull(FK_FISH_ID)

(
  loki_tissue <- loki_tissue_og %>%
    dplyr::filter(
      FK_FISH_ID %in% erb_2017_oto_fish_ids,
      PK_TISSUE_TYPE == "Heart-bulbus arteriosus",
      IS_MISSING_PAIRED_DATA_EXISTS == 0,
      WELL_HAS_MORE_THAN_ONE_SAMPLE == 0
    ) %>%
    dplyr::rename(
      silly = SILLY_CODE,
      fish_id = FK_FISH_ID,
      tissue_type = PK_TISSUE_TYPE,
      dwp_barcode = DNA_TRAY_CODE,
      dwp_well = DNA_TRAY_WELL_CODE
    ) %>%
    tidyr::unite(
      col = "silly_source",
      c(silly, fish_id),
      sep = "_",
      remove = FALSE
    ) %>%
    dplyr::select(
      silly,
      fish_id,
      silly_source,
      tissue_type,
      dwp_barcode,
      dwp_well
    )
)

Salmon Biological Data

Sex and otolith read data lives here…

(oceanak_og <- readr::read_csv(file = "../data/Erb 2017 AHRP Salmon Biological Data 20220321_151027.csv"))
Rows: 14955 Columns: 22
-- Column specification -------------------------------------------------------------------------------------------------------------
Delimiter: ","
chr  (9): SILLY_CODE, SEX, TISSUE_TYPE, DNA_TRAY_CODE, LOCATION_CODE, SAMPLE_ID, OTOLITH_MARK_PRESENT, OTOLITH_MARK_ID, OTOLITH_M...
dbl  (7): COLLECTION_ID, FISH_ID, LENGTH_MM, DNA_TRAY_WELL_CODE, SAMPLE_YEAR, IS_MISSING_PAIRED_DATA_EXISTS, WELL_HAS_MORE_THAN_O...
lgl  (5): TARGET_DNA_TRAY_CODE, TARGET_DNA_TRAY_WELL_POS, TARGET_CONTAINER_ARRAY_TYPE_ID, CONTAINER_ARRAY_TYPE, DETERMINATION_COL...
dttm (1): SAMPLE_DATE

i Use `spec()` to retrieve the full column specification for this data.
i Specify the column types or set `show_col_types = FALSE` to quiet this message.

Modify, filter for silly codes of interest and tissue type “Heart-bulbus arteriosus”

(
  oceanak <- oceanak_og %>%
    dplyr::filter(
      TISSUE_TYPE == "Heart-bulbus arteriosus"
    ) %>%
    dplyr::rename(
      silly = SILLY_CODE,
      fish_id = FISH_ID,
      tissue_type = TISSUE_TYPE,
      dwp_barcode = DNA_TRAY_CODE,
      dwp_well = DNA_TRAY_WELL_CODE,
      sample_date = SAMPLE_DATE,
      sex = SEX,
      otolith_mark_present = OTOLITH_MARK_PRESENT
    ) %>%
    dplyr::mutate(sample_date = lubridate::ymd(sample_date)) %>% 
    tidyr::unite(
      col = "silly_source",
      c(silly, fish_id),
      sep = "_",
      remove = FALSE
    ) %>%
    dplyr::select(
      silly_source,
      sample_date,
      sex,
      otolith_mark_present
    )
)

Join

Join all two of these data sources into something useful, then filter by our collections (Duck and Gregorioff 2014), non-missing tissue, natural-origin, split evenly across silly codes and sexes.

(join_duck_greg <- loki_tissue %>% 
   dplyr::left_join(oceanak, by = "silly_source")
)

Extraction Selection

From each silly, grab the first 9 fish from each sex that are not otolith marked (i.e. natural-origin fish). Total of 18 fish per silly, 36 fish per sampling unit (early and late are still one sampling unit).

(
  extraction_erb_2017 <- join_duck_greg %>%
    dplyr::filter(otolith_mark_present == "NO",
                  sex != "U") %>%
    dplyr::group_by(silly, sex) %>%
    dplyr::slice_sample(n = 18) %>%
    dplyr::ungroup() %>% 
    dplyr::arrange(silly, fish_id) %>% 
    dplyr::select(
      silly_source,
      silly,
      fish_id,
      dwp_barcode,
      dwp_well,
      tissue_type,
      sample_date,
      sex,
      otolith_mark_present
    )
)

Write it out for posterity

readr::write_csv(x = extraction_erb_2017, file = "../output/extraction_selection_PERB17.csv")

Duck River 2013

Got sex data from Wei on 3/21/22

Need the tissue information from LOKI tissue table Need the sex data from LOKI fish table Need the otolith data from warehouse

Pick fish and format for extraction (use PWS Pink as a template)

Import Data

LOKI Tissue Table

DWP information and tissue missing data lives here…

(loki_tissue_og <- readr::read_csv(file = "../data/LOKI_tissue_GEN_SAMPLED_FISH_TISSUE_PDUCK13_20220322_103543.csv"))
Rows: 399 Columns: 47
-- Column specification -------------------------------------------------------------------------------------------------------------
Delimiter: ","
chr  (15): SILLY_CODE, PK_TISSUE_TYPE, CAPTURE_LOCATION, EXHAUSTED_HOW, EXHAUSTED_BY, STORAGE_ID, UNIT, SLOT, DNA_TRAY_WELL_POS, ...
dbl  (12): FK_COLLECTION_ID, FK_FISH_ID, SHELF_RACK, LATITUDE, LONGITUDE, DNA_TRAY_CODE, DNA_TRAY_WELL_CODE, IS_MISSING_PAIRED_DA...
lgl  (16): VIAL_BARCODE, MESH_SIZE, MESH_SIZE_COMMENT, AGENCY, DNA_TRAY_WORKBENCH_ID, OTHER_AGENCY_KEY, OTO_INVENTORY_COMMENT, CO...
dttm  (4): CAPTURE_DATE, EXHAUSTED_DATE, END_CAPTURE_DATE, COLLECTION_DATE

i Use `spec()` to retrieve the full column specification for this data.
i Specify the column types or set `show_col_types = FALSE` to quiet this message.

Modify, filter for silly codes of interest and remove any fish with knwon missing tissues

(
  loki_tissue <- loki_tissue_og %>%
    dplyr::filter(
      SILLY_CODE %in% c("PDUCK13"),
      PK_TISSUE_TYPE == "Axillary Process",
      is.na(IS_MISSING_PAIRED_DATA_EXISTS),
      is.na(WELL_HAS_MORE_THAN_ONE_SAMPLE)
    ) %>%
    dplyr::rename(
      silly = SILLY_CODE,
      fish_id = FK_FISH_ID,
      tissue_type = PK_TISSUE_TYPE,
      dwp_barcode = DNA_TRAY_CODE,
      dwp_well = DNA_TRAY_WELL_CODE
    ) %>%
    tidyr::unite(
      col = "silly_source",
      c(silly, fish_id),
      sep = "_",
      remove = FALSE
    ) %>%
    dplyr::select(
      silly,
      fish_id,
      silly_source,
      tissue_type,
      dwp_barcode,
      dwp_well
    )
)

LOKI Fish Table

Sex data lives here…

(loki_fish_og <- readr::read_csv(file = "../data/LOKI_tissue_GEN_SAMPLED_FISH_PDUCK13_20220322_104648.csv"))
Rows: 152 Columns: 27
-- Column specification -------------------------------------------------------------------------------------------------------------
Delimiter: ","
chr  (2): SILLY_CODE, SEX
dbl  (7): FK_COLLECTION_ID, FISH_ID, AGE_X, AGE_Y, YEAR_SAMPLED, SCALE_CARD_NUM, SCALE_CARD_POS
lgl (18): LENGTH, WEIGHT, SAMPLE_DATE_OLD, SAMPLE_DATE, STAT_WEEK_OLD, STAT_WEEK, PORT_CODE_OLD, PORT_CODE, STAT_AREA, DISTRICT_G...

i Use `spec()` to retrieve the full column specification for this data.
i Specify the column types or set `show_col_types = FALSE` to quiet this message.

Modify, filter for silly codes of interest

(
  loki_fish <- loki_fish_og %>%
    dplyr::filter(
      SILLY_CODE == "PDUCK13"
    ) %>%
    dplyr::rename(
      silly = SILLY_CODE,
      fish_id = FISH_ID,
      sex = SEX
    ) %>%
    tidyr::unite(
      col = "silly_source",
      c(silly, fish_id),
      sep = "_",
      remove = TRUE
    ) %>%
    dplyr::select(silly_source, sex)
)

Salmon Biological Data

Otolith read data lives here…

(oceanak_og <- readr::read_csv(file = "../data/Duck 2013 AHRP Salmon Biological Data 20220322_103611.csv"))
Rows: 304 Columns: 22
-- Column specification -------------------------------------------------------------------------------------------------------------
Delimiter: ","
chr  (5): SILLY_CODE, TISSUE_TYPE, LOCATION_CODE, OTOLITH_MARK_PRESENT, OTOLITH_MARK_STATUS_CODE
dbl  (8): COLLECTION_ID, FISH_ID, DNA_TRAY_CODE, DNA_TRAY_WELL_CODE, SAMPLE_ID, SAMPLE_YEAR, IS_MISSING_PAIRED_DATA_EXISTS, WELL_...
lgl  (8): SEX, LENGTH_MM, OTOLITH_MARK_ID, TARGET_DNA_TRAY_CODE, TARGET_DNA_TRAY_WELL_POS, TARGET_CONTAINER_ARRAY_TYPE_ID, CONTAI...
dttm (1): SAMPLE_DATE

i Use `spec()` to retrieve the full column specification for this data.
i Specify the column types or set `show_col_types = FALSE` to quiet this message.

Modify, filter for silly codes of interest and tissue type “Otolith”

(
  oceanak <- oceanak_og %>%
    dplyr::filter(
      SILLY_CODE == "PDUCK13",
      TISSUE_TYPE == "Otolith"
    ) %>%
    dplyr::rename(
      silly = SILLY_CODE,
      fish_id = FISH_ID,
      tissue_type = TISSUE_TYPE,
      dwp_barcode = DNA_TRAY_CODE,
      dwp_well = DNA_TRAY_WELL_CODE,
      otolith_mark_present = OTOLITH_MARK_PRESENT
    ) %>%
    tidyr::unite(
      col = "silly_source",
      c(silly, fish_id),
      sep = "_",
      remove = FALSE
    ) %>%
    dplyr::select(
      silly_source,
      otolith_mark_present
    )
)

Join

Join all three of these data sources into something useful, then filter by our collections (Duck 13), non-missing tissue, natural-origin, split evenly across silly codes and sexes.

(join_duck_2013 <- loki_tissue %>% 
   dplyr::left_join(loki_fish, by = "silly_source") %>% 
   dplyr::left_join(oceanak, by = "silly_source")
)

Extraction Selection

From each silly, grab the first 18 fish from each sex that are not otolith marked (i.e. natural-origin fish). Total of 36 fish per silly, 36 fish per sampling unit.

(
  extraction_duck_2013 <- join_duck_2013 %>%
    dplyr::filter(otolith_mark_present == "NO",
                  sex != "U") %>%
    dplyr::group_by(silly, sex) %>%
    dplyr::slice_min(order_by = fish_id, n = 18) %>%
    dplyr::ungroup() %>% 
    dplyr::arrange(silly, fish_id) %>% 
    dplyr::select(
      silly_source,
      silly,
      fish_id,
      dwp_barcode,
      dwp_well,
      tissue_type,
      sex,
      otolith_mark_present
    )
)

Write it out for posterity

readr::write_csv(x = extraction_duck_2013, file = "../output/extraction_selection_PDUCK13.csv")

Stockdale 2016

Need hatchery strays and natural-origin homing fish (i.e. those with natural-origin parents)

Natural-origin Homing

Split by sex, sampled throughout the season

Import Data

Bad practice, but I’m going to grab output data from PWS-Pink-Parentage

(
  all_streams_parents_paired_14_16_cross <-
    readr::read_csv(file = "../../PWS Pink/GitHub-PWS-Pink-Parentage/Stockdale_Hogan_Gilmour_Paddy_Erb/all_streams_parents_paired_14_16_cross.csv")
)
Rows: 1360 Columns: 89
-- Column specification -------------------------------------------------------------------------------------------------------------
Delimiter: ","
chr  (35): offspring_id, stream_off, origin_off, sex_off, intertidal_off, otolith_mark_present_off, silly_off, sample_off, dna_tr...
dbl  (41): year_off, DOY_off, length_off, distance_mouth_off, distance_tide_off, fish_id_off, dna_tray_well_code_off, riverdist_s...
lgl  (10): otolith_mark_id_off, pre_spawn_off, partial_spawn_off, preyed_upon_off, pre_spawn_sire, pre_spawn_dam, partial_spawn_s...
date  (3): date_off, date_sire, date_dam

i Use `spec()` to retrieve the full column specification for this data.
i Specify the column types or set `show_col_types = FALSE` to quiet this message.
(
  all_streams_parents_paired_14_16 <-
    readr::read_csv(file = "../../PWS Pink/GitHub-PWS-Pink-Parentage/Stockdale_Hogan_Gilmour_Paddy_Erb/all_streams_parents_paired_14_16.csv")
)
Rows: 7988 Columns: 59
-- Column specification -------------------------------------------------------------------------------------------------------------
Delimiter: ","
chr  (23): offspring_id, parent, parent_id, stream_off, origin_off, sex_off, intertidal_off, otolith_mark_present_off, silly_off,...
dbl  (27): year_off, DOY_off, length_off, distance_mouth_off, distance_tide_off, fish_id_off, dna_tray_well_code_off, riverdist_s...
lgl   (7): otolith_mark_id_off, pre_spawn_off, partial_spawn_off, preyed_upon_off, pre_spawn_par, partial_spawn_par, preyed_upon_par
date  (2): date_off, date_par

i Use `spec()` to retrieve the full column specification for this data.
i Specify the column types or set `show_col_types = FALSE` to quiet this message.

Choose from NN crosses

Filter for Stockdale and only

stockdale_2016_natural_selection_NN_cross <- all_streams_parents_paired_14_16_cross %>% 
  dplyr::filter(stream_off == stream_sire,
                stream_off == "Stockdale",
                origin_sire == origin_dam,
                origin_sire == "Natural") %>% 
  dplyr::group_by(mating_id) %>% 
  dplyr::slice_sample(n = 1, replace = FALSE) %>% 
  dplyr::group_by(parent_id_sire) %>% 
  dplyr::slice_sample(n = 1, replace = FALSE) %>% 
  dplyr::group_by(parent_id_dam) %>% 
  dplyr::slice_sample(n = 1, replace = FALSE) %>% 
  dplyr::ungroup() 

stockdale_2016_natural_selection_NN_cross %>% 
  dplyr::count(sex_off)

Modify for extraction format

(
  stockdale_2016_natural_selection_NN_cross <-
    stockdale_2016_natural_selection_NN_cross %>%
    dplyr::rename(
      silly = silly_off,
      fish_id = fish_id_off,
      dwp_barcode = dna_tray_code_off,
      dwp_well = dna_tray_well_code_off,
      sample_date = date_off,
      sex = sex_off,
      otolith_mark_present = otolith_mark_present_off
    ) %>%
    dplyr::mutate(tissue_type = "Heart-bulbus arteriosus") %>%
    tidyr::unite(
      col = "silly_source",
      c(silly, fish_id),
      sep = "_",
      remove = FALSE
    ) %>%
    dplyr::arrange(silly, fish_id) %>%
    dplyr::select(
      silly_source,
      silly,
      fish_id,
      dwp_barcode,
      dwp_well,
      tissue_type,
      sample_date,
      sex,
      otolith_mark_present
    )
)

Still need 1 more Male, pick from dyad data

Chose from N dyads

(
  stockdale_2016_natural_selection_N_dyad <-
    all_streams_parents_paired_14_16 %>%
    dplyr::rename(
      silly = silly_off,
      fish_id = fish_id_off,
      dwp_barcode = dna_tray_code_off,
      dwp_well = dna_tray_well_code_off,
      sample_date = date_off,
      sex = sex_off,
      otolith_mark_present = otolith_mark_present_off
    ) %>%
    dplyr::mutate(tissue_type = "Heart-bulbus arteriosus") %>%
    tidyr::unite(
      col = "silly_source",
      c(silly, fish_id),
      sep = "_",
      remove = FALSE
    ) %>%
    dplyr::filter(
      stream_off == stream_par,
      stream_off == "Stockdale",
      origin_par == "Natural",
      sex == "Male",
      !(
        silly_source %in% stockdale_2016_natural_selection_NN_cross$silly_source
      ),
      !(
        parent_id %in% all_streams_parents_paired_14_16_cross$parent_id_dam
      ),
      !(
        parent_id %in% all_streams_parents_paired_14_16_cross$parent_id_sire
      )
    ) %>%
    dplyr::group_by(sex) %>%
    dplyr::slice_sample(n = 1, replace = FALSE) %>%
    dplyr::ungroup() %>% 
    dplyr::arrange(silly, fish_id) %>%
    dplyr::select(
      silly_source,
      silly,
      fish_id,
      dwp_barcode,
      dwp_well,
      tissue_type,
      sample_date,
      sex,
      otolith_mark_present
    )
)

stockdale_2016_natural_selection_N_dyad %>%
  dplyr::count(sex)

Extraction Selection

Bind together, make sure no duplicates

(
  extraction_PSTOCK16_natural <-
    dplyr::bind_rows(
      stockdale_2016_natural_selection_NN_cross,
      stockdale_2016_natural_selection_N_dyad
    ) %>%
    dplyr::arrange(silly, fish_id) %>% 
    dplyr::distinct()
)

Double check sample sizes

extraction_PSTOCK16_natural %>% 
  dplyr::count(silly)

extraction_PSTOCK16_natural %>% 
  dplyr::count(silly, sex)

Write it out for posterity

readr::write_csv(x = extraction_PSTOCK16_natural, file = "../output/extraction_PSTOCK16_natural.csv")

Stockdale 2015

Need hatchery strays and natural-origin homing fish (i.e. those with natural-origin parents)

Natural-origin Homing

Split by sex, sampled throughout the season

Import Data

Bad practice, but I’m going to grab output data from PWS-Pink-Parentage

(
  stockdale_parents_paired_13_15 <-
    readr::read_csv(file = "../../PWS Pink/GitHub-PWS-Pink-Parentage/Stockdale/stock_parents_paired_13_15.csv")
)
Rows: 129 Columns: 32
-- Column specification ------------------------------------------------------------------------------------------------------------
Delimiter: ","
chr  (17): Offspring, Parent, Parent_ID, SILLY.off, Sample Date.off, SEX.off, Otolith Mark Present.off, origin.off, Sex.off, SIL...
dbl  (12): Fish ID.off, DNA Tray Code.off, DNA Tray Well Code.off, Sample Year.off, Length Mm.off, DOY.off, Fish ID.par, DNA Tra...
lgl   (1): Otolith Mark ID.off
date  (2): date.off, date.par

i Use `spec()` to retrieve the full column specification for this data.
i Specify the column types or set `show_col_types = FALSE` to quiet this message.

Choose from NN crosses

There are is no triad data for the 2013/2015 pedigrees

Chose from N dyads

(
  stockdale_2015_natural_selection_N_dyad <-
    stockdale_parents_paired_13_15 %>%
    dplyr::rename(
      silly = SILLY.off,
      fish_id = "Fish ID.off",
      dwp_barcode = "DNA Tray Code.off",
      dwp_well = "DNA Tray Well Code.off",
      sample_date = date.off,
      sex = SEX.off,
      otolith_mark_present = "Otolith Mark Present.off"
    ) %>%
    dplyr::mutate(tissue_type = "Heart-bulbus arteriosus") %>%
    tidyr::unite(
      col = "silly_source",
      c(silly, fish_id),
      sep = "_",
      remove = FALSE
    ) %>%
    dplyr::filter(origin.par == "Natural") %>%
    dplyr::group_by(sex) %>%
    dplyr::slice_sample(n = 18, replace = FALSE) %>%
    dplyr::ungroup() %>% 
    dplyr::arrange(silly, fish_id) %>%
    dplyr::select(
      silly_source,
      silly,
      fish_id,
      dwp_barcode,
      dwp_well,
      tissue_type,
      sample_date,
      sex,
      otolith_mark_present
    )
)

stockdale_2015_natural_selection_N_dyad %>%
  dplyr::count(sex)

Extraction Selection

Bind together, make sure no duplicates

(
  extraction_PSTOCK15_natural <-
    dplyr::bind_rows(
      stockdale_2015_natural_selection_N_dyad
    ) %>%
    dplyr::arrange(silly, fish_id) %>% 
    dplyr::distinct()
)

Double check sample sizes

extraction_PSTOCK15_natural %>% 
  dplyr::count(silly)

extraction_PSTOCK15_natural %>% 
  dplyr::count(silly, sex)

Write it out for posterity

readr::write_csv(x = extraction_PSTOCK15_natural, file = "../output/extraction_PSTOCK15_natural.csv")

Hogan 2016

Need hatchery strays and natural-origin homing fish (i.e. those with natural-origin parents)

Natural-origin Homing

Split by sex, sampled throughout the season

Import Data

Bad practice, but I’m going to grab output data from PWS-Pink-Parentage

(
  all_streams_parents_paired_14_16_cross <-
    readr::read_csv(file = "../../PWS Pink/GitHub-PWS-Pink-Parentage/Stockdale_Hogan_Gilmour_Paddy_Erb/all_streams_parents_paired_14_16_cross.csv")
)
Rows: 1360 Columns: 89
-- Column specification ------------------------------------------------------------------------------------------------------------
Delimiter: ","
chr  (35): offspring_id, stream_off, origin_off, sex_off, intertidal_off, otolith_mark_present_off, silly_off, sample_off, dna_t...
dbl  (41): year_off, DOY_off, length_off, distance_mouth_off, distance_tide_off, fish_id_off, dna_tray_well_code_off, riverdist_...
lgl  (10): otolith_mark_id_off, pre_spawn_off, partial_spawn_off, preyed_upon_off, pre_spawn_sire, pre_spawn_dam, partial_spawn_...
date  (3): date_off, date_sire, date_dam

i Use `spec()` to retrieve the full column specification for this data.
i Specify the column types or set `show_col_types = FALSE` to quiet this message.
(
  all_streams_parents_paired_14_16 <-
    readr::read_csv(file = "../../PWS Pink/GitHub-PWS-Pink-Parentage/Stockdale_Hogan_Gilmour_Paddy_Erb/all_streams_parents_paired_14_16.csv")
)
Rows: 7988 Columns: 59
-- Column specification ------------------------------------------------------------------------------------------------------------
Delimiter: ","
chr  (23): offspring_id, parent, parent_id, stream_off, origin_off, sex_off, intertidal_off, otolith_mark_present_off, silly_off...
dbl  (27): year_off, DOY_off, length_off, distance_mouth_off, distance_tide_off, fish_id_off, dna_tray_well_code_off, riverdist_...
lgl   (7): otolith_mark_id_off, pre_spawn_off, partial_spawn_off, preyed_upon_off, pre_spawn_par, partial_spawn_par, preyed_upon...
date  (2): date_off, date_par

i Use `spec()` to retrieve the full column specification for this data.
i Specify the column types or set `show_col_types = FALSE` to quiet this message.

Choose from NN crosses

Filter for Hogan and only

hogan_2016_natural_selection_NN_cross <- all_streams_parents_paired_14_16_cross %>% 
  dplyr::filter(stream_off == stream_sire,
                stream_off == "Hogan",
                origin_sire == origin_dam,
                origin_sire == "Natural") %>% 
  dplyr::group_by(mating_id) %>% 
  dplyr::slice_sample(n = 1, replace = FALSE) %>% 
  dplyr::group_by(parent_id_sire) %>% 
  dplyr::slice_sample(n = 1, replace = FALSE) %>% 
  dplyr::group_by(parent_id_dam) %>% 
  dplyr::slice_sample(n = 1, replace = FALSE) %>% 
  dplyr::ungroup() 

hogan_2016_natural_selection_NN_cross %>% 
  dplyr::count(sex_off)

This is dumb, very few NN crosses, just use the dyad data.

Chose from N dyads

(
  hogan_2016_natural_selection_N_dyad <-
    all_streams_parents_paired_14_16 %>%
    dplyr::rename(
      silly = silly_off,
      fish_id = fish_id_off,
      dwp_barcode = dna_tray_code_off,
      dwp_well = dna_tray_well_code_off,
      sample_date = date_off,
      sex = sex_off,
      otolith_mark_present = otolith_mark_present_off
    ) %>%
    dplyr::mutate(tissue_type = "Heart-bulbus arteriosus") %>%
    tidyr::unite(
      col = "silly_source",
      c(silly, fish_id),
      sep = "_",
      remove = FALSE
    ) %>%
    dplyr::filter(
      stream_off == stream_par,
      stream_off == "Hogan",
      origin_par == "Natural",
      !(
        parent_id %in% all_streams_parents_paired_14_16_cross$parent_id_dam
      ),
      !(
        parent_id %in% all_streams_parents_paired_14_16_cross$parent_id_sire
      )
    ) %>%
    dplyr::group_by(sex) %>%
    dplyr::slice_sample(n = 18, replace = FALSE) %>%
    dplyr::ungroup() %>% 
    dplyr::arrange(silly, fish_id) %>%
    dplyr::select(
      silly_source,
      silly,
      fish_id,
      dwp_barcode,
      dwp_well,
      tissue_type,
      sample_date,
      sex,
      otolith_mark_present
    )
)

hogan_2016_natural_selection_N_dyad %>%
  dplyr::count(sex)

Extraction Selection

Bind together, make sure no duplicates

(
  extraction_PHOGAN16_natural <-
    dplyr::bind_rows(
      hogan_2016_natural_selection_N_dyad
    ) %>%
    dplyr::arrange(silly, fish_id) %>% 
    dplyr::distinct()
)

Double check sample sizes

extraction_PHOGAN16_natural %>% 
  dplyr::count(silly)

extraction_PHOGAN16_natural %>% 
  dplyr::count(silly, sex)

Write it out for posterity

readr::write_csv(x = extraction_PHOGAN16_natural, file = "../output/extraction_PHOGAN16_natural.csv")

Hogan 2015

Need hatchery strays and natural-origin homing fish (i.e. those with natural-origin parents)

Natural-origin Homing

Split by sex, sampled throughout the season

Import Data

Bad practice, but I’m going to grab output data from PWS-Pink-Parentage

(
  hogan_parents_paired_13_15 <-
    readr::read_csv(file = "../../PWS Pink/GitHub-PWS-Pink-Parentage/Hogan/hogan_parents_paired_13_15.csv")
)
Rows: 110 Columns: 32
-- Column specification ------------------------------------------------------------------------------------------------------------
Delimiter: ","
chr  (17): Offspring, Parent, Parent_ID, SILLY.off, Sample Date.off, SEX.off, Otolith Mark Present.off, origin.off, Sex.off, SIL...
dbl  (12): Fish ID.off, DNA Tray Code.off, DNA Tray Well Code.off, Sample Year.off, Length Mm.off, DOY.off, Fish ID.par, DNA Tra...
lgl   (1): Otolith Mark ID.off
date  (2): date.off, date.par

i Use `spec()` to retrieve the full column specification for this data.
i Specify the column types or set `show_col_types = FALSE` to quiet this message.

Choose from NN crosses

There are is no triad data for the 2013/2015 pedigrees

Chose from N dyads

(
  hogan_2015_natural_selection_N_dyad <-
    hogan_parents_paired_13_15 %>%
    dplyr::rename(
      silly = SILLY.off,
      fish_id = "Fish ID.off",
      dwp_barcode = "DNA Tray Code.off",
      dwp_well = "DNA Tray Well Code.off",
      sample_date = date.off,
      sex = SEX.off,
      otolith_mark_present = "Otolith Mark Present.off"
    ) %>%
    dplyr::mutate(tissue_type = "Heart-bulbus arteriosus") %>%
    tidyr::unite(
      col = "silly_source",
      c(silly, fish_id),
      sep = "_",
      remove = FALSE
    ) %>%
    dplyr::filter(origin.par == "Natural") %>%
    dplyr::group_by(sex) %>%
    dplyr::slice_sample(n = 18, replace = FALSE) %>%
    dplyr::ungroup() %>% 
    dplyr::arrange(silly, fish_id) %>%
    dplyr::select(
      silly_source,
      silly,
      fish_id,
      dwp_barcode,
      dwp_well,
      tissue_type,
      sample_date,
      sex,
      otolith_mark_present
    )
)

hogan_2015_natural_selection_N_dyad %>%
  dplyr::count(sex)

Extraction Selection

Bind together, make sure no duplicates

(
  extraction_PHOGAN15_natural <-
    dplyr::bind_rows(
      hogan_2015_natural_selection_N_dyad
    ) %>%
    dplyr::arrange(silly, fish_id) %>% 
    dplyr::distinct()
)

Double check sample sizes

extraction_PHOGAN15_natural %>% 
  dplyr::count(silly)

extraction_PHOGAN15_natural %>% 
  dplyr::count(silly, sex)

Write it out for posterity

readr::write_csv(x = extraction_PHOGAN15_natural, file = "../output/extraction_PHOGAN15_natural.csv")

Hatchery-origin straying

For Stockdale and Hogan 2015 and 2016 Split by sex and hatchery (only AFK and WHN, no broodsource for CCH and too few VFDA) Random with respect to sample location and sample date

Import Data

Salmon Biological Data

Otolith read data lives here…

(
  oceanak_hatchery_og <-
    readr::read_csv(file = "../data/Stockdale 2015-2016 Hogan 2015-2016 Spring 2014-2015 AHRP Salmon Biological Data 20220322_115608.csv")
)
Rows: 80100 Columns: 22
-- Column specification -------------------------------------------------------------------------------------------------------------
Delimiter: ","
chr  (9): SILLY_CODE, SEX, TISSUE_TYPE, DNA_TRAY_CODE, LOCATION_CODE, SAMPLE_ID, OTOLITH_MARK_PRESENT, OTOLITH_MARK_ID, OTOLITH_M...
dbl  (7): COLLECTION_ID, FISH_ID, LENGTH_MM, DNA_TRAY_WELL_CODE, SAMPLE_YEAR, IS_MISSING_PAIRED_DATA_EXISTS, WELL_HAS_MORE_THAN_O...
lgl  (5): TARGET_DNA_TRAY_CODE, TARGET_DNA_TRAY_WELL_POS, TARGET_CONTAINER_ARRAY_TYPE_ID, CONTAINER_ARRAY_TYPE, DETERMINATION_COL...
dttm (1): SAMPLE_DATE

i Use `spec()` to retrieve the full column specification for this data.
i Specify the column types or set `show_col_types = FALSE` to quiet this message.

Modify, filter for silly codes of interest and tissue type “Otolith”, and only AFK and WNH individuals

(
  oceanak_hatchery <- oceanak_hatchery_og %>%
    dplyr::filter(
      SILLY_CODE %in% c("PSTOCK16", "PSTOCK15", "PHOGAN16", "PHOGAN15"),
      TISSUE_TYPE == "Heart-bulbus arteriosus",
      OTOLITH_MARK_PRESENT == "YES",
      SEX != "U"
    ) %>%
    dplyr::rename(
      silly = SILLY_CODE,
      fish_id = FISH_ID,
      tissue_type = TISSUE_TYPE,
      dwp_barcode = DNA_TRAY_CODE,
      dwp_well = DNA_TRAY_WELL_CODE,
      sample_date = SAMPLE_DATE,
      sex = SEX,
      otolith_mark_present = OTOLITH_MARK_PRESENT,
      otolith_mark_id = OTOLITH_MARK_ID
    ) %>%
    dplyr::mutate(
      sample_date = lubridate::ymd(sample_date),
      hatchery = stringr::str_sub(
        string = otolith_mark_id,
        start = 1,
        end = 3
      )
    ) %>%
    dplyr::filter(hatchery %in% c("AFK", "WNH")) %>% 
    tidyr::unite(
      col = "silly_source",
      c(silly, fish_id),
      sep = "_",
      remove = FALSE
    ) %>%
    dplyr::select(
      silly_source,
      silly,
      fish_id,
      dwp_barcode,
      dwp_well,
      tissue_type,
      sample_date,
      sex,
      hatchery,
      otolith_mark_present,
      otolith_mark_id
    )
)

How many?

oceanak_hatchery %>% 
  dplyr::count(silly, sex, hatchery)

Extraction Selection

From each silly, grab the first 18 fish from each sex that are not otolith marked (i.e. natural-origin fish). Total of 36 fish per silly, 36 fish per sampling unit.

(
  extraction_hatchery_stray <- oceanak_hatchery %>%
    dplyr::filter(otolith_mark_present == "YES",
                  sex != "U") %>%
    dplyr::group_by(silly, sex, hatchery) %>%
    dplyr::slice_sample(n = 9, replace = FALSE) %>%
    dplyr::ungroup() %>% 
    dplyr::arrange(silly, fish_id) %>% 
    dplyr::select(
      silly_source,
      silly,
      fish_id,
      dwp_barcode,
      dwp_well,
      tissue_type,
      sample_date,
      sex,
      hatchery,
      otolith_mark_present,
      otolith_mark_id
    )
)

Double check

extraction_hatchery_stray %>% 
  dplyr::count(silly, sex, hatchery)

Missing 7 females and 8 males from PSTOCK16, WNH. Will replace with AFK fish.

(
  extraction_hatchery_stray_PSTOCK16_AFK_female <- oceanak_hatchery %>%
    dplyr::filter(silly == "PSTOCK16",
                  sex == "F",
                  hatchery == "AFK") %>%
    dplyr::group_by(silly, sex, hatchery) %>%
    dplyr::slice_sample(n = 7, replace = FALSE) %>%
    dplyr::ungroup() %>% 
    dplyr::arrange(silly, fish_id) %>% 
    dplyr::select(
      silly_source,
      silly,
      fish_id,
      dwp_barcode,
      dwp_well,
      tissue_type,
      sample_date,
      sex,
      hatchery,
      otolith_mark_present,
      otolith_mark_id
    )
)

(
  extraction_hatchery_stray_PSTOCK16_AFK_male <- oceanak_hatchery %>%
    dplyr::filter(silly == "PSTOCK16",
                  sex == "M",
                  hatchery == "AFK") %>%
    dplyr::group_by(silly, sex, hatchery) %>%
    dplyr::slice_sample(n = 8, replace = FALSE) %>%
    dplyr::ungroup() %>% 
    dplyr::arrange(silly, fish_id) %>% 
    dplyr::select(
      silly_source,
      silly,
      fish_id,
      dwp_barcode,
      dwp_well,
      tissue_type,
      sample_date,
      sex,
      hatchery,
      otolith_mark_present,
      otolith_mark_id
    )
)

Bind together, make sure no duplicates

(
  extraction_hatchery_stray_final <-
    dplyr::bind_rows(
      extraction_hatchery_stray,
      extraction_hatchery_stray_PSTOCK16_AFK_female,
      extraction_hatchery_stray_PSTOCK16_AFK_male
    ) %>%
    dplyr::distinct()
)

Double check sample sizes

extraction_hatchery_stray_final %>% 
  dplyr::count(silly)

extraction_hatchery_stray_final %>% 
  dplyr::count(silly, sex)

extraction_hatchery_stray_final %>% 
  dplyr::count(silly, sex, hatchery)

Write it out for posterity

readr::write_csv(x = extraction_hatchery_stray_final, file = "../output/extraction_selection_hatchery_stray.csv")

Wild Systems - No Strays

Spring Creek! Split by sex, sampled throughout the season

Import Data

Salmon Biological Data

Otolith read data lives here…

(
  oceanak_spring_og <-
    readr::read_csv(file = "../data/Spring 2014-2015 AHRP Salmon Biological Data 20220322_122538.csv")
)
Warning: One or more parsing issues, see `problems()` for details
Rows: 25240 Columns: 22
-- Column specification ----------------------------------------------------------------------------------------
Delimiter: ","
chr  (8): SILLY_CODE, SEX, TISSUE_TYPE, DNA_TRAY_CODE, LOCATION_CODE, SAMPLE_ID, OTOLITH_MARK_PRESENT, OTOLI...
dbl  (7): COLLECTION_ID, FISH_ID, LENGTH_MM, DNA_TRAY_WELL_CODE, SAMPLE_YEAR, IS_MISSING_PAIRED_DATA_EXISTS,...
lgl  (6): OTOLITH_MARK_ID, TARGET_DNA_TRAY_CODE, TARGET_DNA_TRAY_WELL_POS, TARGET_CONTAINER_ARRAY_TYPE_ID, C...
dttm (1): SAMPLE_DATE

i Use `spec()` to retrieve the full column specification for this data.
i Specify the column types or set `show_col_types = FALSE` to quiet this message.

Modify, filter for silly codes of interest and tissue type “Otolith”

(
  oceanak_spring <- oceanak_spring_og %>%
    dplyr::filter(
      SILLY_CODE %in% c("PSPRIN14", "PSPRIN15"),
      TISSUE_TYPE == "Heart-bulbus arteriosus",
      OTOLITH_MARK_PRESENT == "NO",
      SEX != "U"
    ) %>%
    dplyr::rename(
      silly = SILLY_CODE,
      fish_id = FISH_ID,
      tissue_type = TISSUE_TYPE,
      dwp_barcode = DNA_TRAY_CODE,
      dwp_well = DNA_TRAY_WELL_CODE,
      sample_date = SAMPLE_DATE,
      sex = SEX,
      otolith_mark_present = OTOLITH_MARK_PRESENT
    ) %>%
    dplyr::mutate(
      sample_date = lubridate::ymd(sample_date)
    ) %>%
    tidyr::unite(
      col = "silly_source",
      c(silly, fish_id),
      sep = "_",
      remove = FALSE
    ) %>%
    dplyr::select(
      silly_source,
      silly,
      fish_id,
      dwp_barcode,
      dwp_well,
      tissue_type,
      sample_date,
      sex,
      otolith_mark_present
    )
)

Extraction Selection

From each silly, grab the first 18 fish from each sex that are not otolith marked (i.e. natural-origin fish). Total of 36 fish per silly, 36 fish per sampling unit.

(
  extraction_spring <- oceanak_spring %>%
    dplyr::filter(otolith_mark_present == "NO",
                  sex != "U") %>%
    dplyr::group_by(silly, sex) %>%
    dplyr::slice_sample(n = 18, replace = FALSE) %>%
    dplyr::ungroup() %>% 
    dplyr::arrange(silly, fish_id) %>% 
    dplyr::select(
      silly_source,
      silly,
      fish_id,
      dwp_barcode,
      dwp_well,
      tissue_type,
      sample_date,
      sex,
      otolith_mark_present
    )
)

Double check

extraction_spring %>% 
  dplyr::count(silly, sex, otolith_mark_present)

Write it out for posterity

readr::write_csv(x = extraction_spring, file = "../output/extraction_selection_PSPRIN14_PSPRIN15.csv")

Extraction Selection take 2 - 3/31/22

Erin noted that several fish were missing from PSPRIN14.

First, let’s read in what we had asked for so we can avoid those.

(extraction_spring <- readr::read_csv(file = "../output/extraction_selection_PSPRIN14_PSPRIN15.csv"))
Rows: 72 Columns: 9
-- Column specification ----------------------------------------------------------------------------------------
Delimiter: ","
chr  (6): silly_source, silly, dwp_barcode, tissue_type, sex, otolith_mark_present
dbl  (2): fish_id, dwp_well
date (1): sample_date

i Use `spec()` to retrieve the full column specification for this data.
i Specify the column types or set `show_col_types = FALSE` to quiet this message.

Here are the sample numbers that Erin noted were missing, so we know what we need to replace.

Which sex?

extraction_spring %>% 
  dplyr::filter(silly == "PSPRIN14",
                fish_id %in% extraction_spring_missing_fish_ids) %>% 
  dplyr::count(silly, sex, otolith_mark_present)

Looks like we need to replace 6 fish from each sex.

(
  extraction_spring_v2 <- oceanak_spring %>%
    dplyr::filter(!silly_source %in% extraction_spring$silly_source,
                  silly == "PSPRIN14",
                  otolith_mark_present == "NO",
                  sex != "U") %>%
    dplyr::group_by(silly, sex) %>%
    dplyr::slice_sample(n = 6, replace = FALSE) %>%
    dplyr::ungroup() %>% 
    dplyr::arrange(silly, fish_id) %>% 
    dplyr::select(
      silly_source,
      silly,
      fish_id,
      dwp_barcode,
      dwp_well,
      tissue_type,
      sample_date,
      sex,
      otolith_mark_present
    )
)

Double check

extraction_spring_v2 %>% 
  dplyr::count(silly, sex, otolith_mark_present)

Write it out for posterity

readr::write_csv(x = extraction_spring_v2, file = "../output/extraction_selection_PSPRIN14_v2.csv")

End…

LS0tDQp0aXRsZTogIkV4dHJhY3Rpb24gTGlzdCBmb3IgUFdTIFBpbmsgU2FsbW9uIFdHUiINCnN1YnRpdGxlOiAiUGlja2luZyBIaXN0b3JpY2FsICsgQ29udGVtcG9yYXJ5IFNhbXBsZXMiDQphdXRob3I6ICJLeWxlIFNoZWRkIg0KZGF0ZTogIjE2IE1hcmNoIDIwMjIiDQpvdXRwdXQ6DQogIGh0bWxfbm90ZWJvb2s6DQogICAgdGhlbWU6IHVuaXRlZA0KICAgIHRvYzogeWVzDQplZGl0b3Jfb3B0aW9uczogDQogIGNodW5rX291dHB1dF90eXBlOiBpbmxpbmUNCi0tLQ0KDQojIFNldHVwDQoNCkNsZWFuIGRpcmVjdG9yeSBhbmQgbG9hZCBwYWNrYWdlcw0KYGBge3Igc2V0dXAsIGluY2x1ZGU9RkFMU0V9DQpybShsaXN0PWxzKCkpDQoNCmtuaXRyOjpvcHRzX2NodW5rJHNldChlY2hvID0gVFJVRSkNCg0KaWYoIXJlcXVpcmUoInBhY21hbiIpKSBpbnN0YWxsLnBhY2thZ2VzKCJwYWNtYW4iKTsgbGlicmFyeShwYWNtYW4pDQoNCnBhY21hbjo6cF9sb2FkKA0KICB0aWR5dmVyc2UsDQogIGx1YnJpZGF0ZSwNCiAgRFQNCikNCg0KIyBzb3VyY2UoIn4vLi4vUi9GdW5jdGlvbnMuR0NMLlIiKSAgIyBkZXZlbG9wIGJyYW5jaCEhIQ0KYGBgDQoNCkhlbHBlciBmdW5jdGlvbiBmb3IgY29udmVydGluZyBhIGxpc3Qgb2YgYHNpbGx5dmVjYCBvbiBjbGlwYm9hcmQgdG8gc2VwYXJhdGVkIGJ5ICI7IiBmb3IgKk9jZWFuQUsqIGxvb2t1cCBhbmQgcGFzdGVkIGJhY2sgdG8gY2xpcGJvYXJkDQpgYGB7cn0NCnNpbGx5dmVjIDwtIHJlYWRDbGlwYm9hcmQoKQ0Kc2lsbHl2ZWMgPC0gc2V0ZGlmZihzaWxseXZlYywgYygiUFNUT0NLMTYiLCAiUFNUT0NLMTciLCAiUEhPR0FOMTYiLCAiUEhPR0FOMTciKSkNCndyaXRlQ2xpcGJvYXJkKHBhc3RlMCh1bmlxdWUoc2lsbHl2ZWMpLCBjb2xsYXBzZSA9ICI7IikpDQpgYGANCg0KIyBPYmplY3RpdmUNCg0KVGhlIG9iamVjdGl2ZSBvZiB0aGlzIG5vdGVib29rcyBpcyB0byBjcmVhdGUgYW4gZXh0cmFjdGlvbiBsaXN0IGZvciBvdXIgY29sbGFib3JhdGl2ZSBQV1MgUGluayBTYWxtb24gd2hvbGUgZ2Vub21lIHJlLXNlcXVlbmNpbmcgKFdHUikgcHJvamVjdCB3aXRoIHRoZSBDaHJpc3RpZSBMYWIgYXQgIFB1cmR1ZSBVbml2ZXJzaXR5LiBUaGUgc3R1ZHkgZGVzaWduIGZvciB0aGlzIGV4dHJhY3Rpb24gbGlzdCBjb21lcyBmcm9tOg0KDQogICAgVjpcRG9jdW1lbnRzXDVfQ29hc3R3aWRlXE11bHRpc3BlY2llc1xBSFJQXFBpbmsgU2FsbW9uIERpc2FzdGVyIEZ1bmRpbmdcUm91bmQyXE9iamVjdGl2ZSAxMSBQV1MgV0dSXFNhbXBsZSBVbml0cy54bHN4DQogICAgU2hlZXQgMg0KDQogICogMjkgc2FtcGxlIHVuaXRzICANCiAgKiAzNiBpbmRpdmlkdWFscyBwZXIgc2FtcGxlcyB1bml0ICANCiAgKiAxLDA0NCB0b3RhbCBpbmRpdmlkdWFscyAgDQoNCiMgQmFja2dyb3VuZA0KDQpUaGlzIHByb2plY3QgaXMgdXNpbmcgbGVmdG92ZXIgUGluayBTYWxtb24gRGlzYXN0ZXIgMjAxNiBmdW5kcyB0byB0cnkgdG8gYWRkcmVzcyBxdWVzdGlvbnMgYWJvdXQgcG90ZW50aWFsIGdlbmV0aWMgbWVjaGFuaXNtcyBjYXVzaW5nIHJlZHVjZWQgUlJTLiBUaGlzIHByb2plY3QgaXMgYnJva2VuIGludG8gdHdvIG1haW4gcXVlc3Rpb25zOiAgDQoNCiAgKiBBIC0gZ2Vub21pYyBldmlkZW5jZSBmb3IgZG9tZXN0aWNhdGlvbiBzZWxlY3Rpb24gb3ZlciB0aW1lIChjb21wYXJpbmcgaGlzdG9yaWNhbCB2cy4gY29udGVtcG9yYXJ5IHZzLiBicm9vZCBzb3VyY2UgY29sbGVjdGlvbnMpICANCiAgKiBCIC0gZ2Vub21pYyBkaWZmZXJlbmNlcyBiZXR3ZWVuIGhhdGNoZXJ5IHN0cmF5cyB2cy4gbmF0dXJhbC1vcmlnaW4gaG9taW5nIGluZGl2aWR1YWxzDQoNCiMjIFNhbXBsZSBVbml0cw0KDQohW1NjcmVlbnNob3Qgb2Ygc2FtcGxlIGRlc2lnbl0oLi4vZGF0YS9zYW1wbGVfdW5pdHMuUE5HKQ0KDQpVc2luZyAib3V0cHV0L1BXUyBQaW5rIFNhbG1vbiBXR1IgRXh0cmFjdGlvbiBMaXN0Lnhsc3giIGFuZCAib3V0cHV0L2V4dHJhY3Rpb25fc2VsZWN0aW9uLnhsc3giIHRvIGhhbmQtcGljayBtb3N0IGV4dHJhY3Rpb25zDQoNCioqVXBkYXRpbmcgdG8gcmVwbGFjZSBHcmVnb3JpZWZmIENyZWVrIDE5OTMgYW5kIFNpd2FzaCBDcmVlayAyMDE1IGFzIHRoZSBWRkRBIGJyb29kIHNvdXJjZSBjb2xsZWN0aW9ucyBmb3IgdGhlIG9kZC1saW5lYWdlKioNCg0KUmVwbGFjaW5nIHdpdGggRHVjayBSaXZlciAxOTEgYW5kIDIwMTMuIER1Y2sgUml2ZXIgd2FzIG5vdCB0aGUgYnJvb2Qgc291cmNlIGZvciBWRkRBLCBidXQgaXQgaXMgdGhlIGNsb3Nlc3Qgc3RyZWFtIGRpc3RhbmNlLXdpc2UuIEdyZWdvcmllZmYgMTk5MyBvbmx5IGhhZCAxNiBhbGV2aW4gc2FtcGxlcyBhbmQgU2l3YXNoIDIwMTUgZGlkIG5vdCBoYXZlIHBhaXJlZCBvdG9saXRoIGRhdGEgKHNvIHByb2JhYmx5IGEgYnVuY2ggb2Ygc3RyYXlzIG1peGVkIGluKS4NCg0KIyBEdWNrIFJpdmVyIDIwMTQgKyBHcmVnb3JpZWZmIENyZWVrIDIwMTQNCg0KTmVlZCB0aGUgdGlzc3VlIGluZm9ybWF0aW9uIGZyb20gKkxPS0kqIHRpc3N1ZSB0YWJsZQ0KTmVlZCB0aGUgc2V4IGRhdGEgZnJvbSAqTE9LSSogZmlzaCB0YWJsZQ0KTmVlZCB0aGUgb3RvbGl0aCBkYXRhIGZyb20gKndhcmVob3VzZSoNCg0KUGljayBmaXNoIGFuZCBmb3JtYXQgZm9yIGV4dHJhY3Rpb24gKHVzZSBQV1MgUGluayBhcyBhIHRlbXBsYXRlKQ0KDQojIyBJbXBvcnQgRGF0YQ0KDQojIyMgTE9LSSBUaXNzdWUgVGFibGUNCg0KRFdQIGluZm9ybWF0aW9uIGFuZCB0aXNzdWUgbWlzc2luZyBkYXRhIGxpdmVzIGhlcmUuLi4NCmBgYHtyfQ0KKGxva2lfdGlzc3VlX29nIDwtIHJlYWRyOjpyZWFkX2NzdihmaWxlID0gIi4uL2RhdGEvTE9LSV90aXNzdWVfR0VOX1NBTVBMRURfRklTSF9USVNTVUUuY3N2IikpDQpgYGANCg0KTW9kaWZ5LCBmaWx0ZXIgZm9yIHNpbGx5IGNvZGVzIG9mIGludGVyZXN0IGFuZCByZW1vdmUgYW55IGZpc2ggd2l0aCBrbndvbiBtaXNzaW5nIHRpc3N1ZXMNCmBgYHtyfQ0KKA0KICBsb2tpX3Rpc3N1ZSA8LSBsb2tpX3Rpc3N1ZV9vZyAlPiUNCiAgICBkcGx5cjo6ZmlsdGVyKA0KICAgICAgYFNpbGx5IENvZGVgICVpbiUgYygiUERVQ0sxNEUiLCAiUERVQ0sxNEwiLCAiUEdSRUcxNEUiLCAiUEdSRUcxNEwiKSwNCiAgICAgIFBLX1RJU1NVRV9UWVBFID09ICJIZWFydCIsDQogICAgICBpcy5uYShJU19NSVNTSU5HX1BBSVJFRF9EQVRBX0VYSVNUUyksDQogICAgICBpcy5uYShXRUxMX0hBU19NT1JFX1RIQU5fT05FX1NBTVBMRSkNCiAgICApICU+JQ0KICAgIGRwbHlyOjpyZW5hbWUoDQogICAgICBzaWxseSA9IGBTaWxseSBDb2RlYCwNCiAgICAgIGZpc2hfaWQgPSBGS19GSVNIX0lELA0KICAgICAgdGlzc3VlX3R5cGUgPSBQS19USVNTVUVfVFlQRSwNCiAgICAgIGR3cF9iYXJjb2RlID0gRE5BX1RSQVlfQ09ERSwNCiAgICAgIGR3cF93ZWxsID0gRE5BX1RSQVlfV0VMTF9DT0RFDQogICAgKSAlPiUNCiAgICB0aWR5cjo6dW5pdGUoDQogICAgICBjb2wgPSAic2lsbHlfc291cmNlIiwNCiAgICAgIGMoc2lsbHksIGZpc2hfaWQpLA0KICAgICAgc2VwID0gIl8iLA0KICAgICAgcmVtb3ZlID0gRkFMU0UNCiAgICApICU+JQ0KICAgIGRwbHlyOjpzZWxlY3QoDQogICAgICBzaWxseSwNCiAgICAgIGZpc2hfaWQsDQogICAgICBzaWxseV9zb3VyY2UsDQogICAgICB0aXNzdWVfdHlwZSwNCiAgICAgIGR3cF9iYXJjb2RlLA0KICAgICAgZHdwX3dlbGwNCiAgICApDQopDQpgYGANCg0KIyMjIExPS0kgRmlzaCBUYWJsZQ0KDQpTZXggZGF0YSBsaXZlcyBoZXJlLi4uDQpgYGB7cn0NCihsb2tpX2Zpc2hfb2cgPC0gcmVhZHI6OnJlYWRfY3N2KGZpbGUgPSAiLi4vZGF0YS9MT0tJX2Zpc2hfQVNMIEltcG9ydC5jc3YiKSkNCmBgYA0KDQpNb2RpZnksIGZpbHRlciBmb3Igc2lsbHkgY29kZXMgb2YgaW50ZXJlc3QNCmBgYHtyfQ0KKA0KICBsb2tpX2Zpc2ggPC0gbG9raV9maXNoX29nICU+JQ0KICAgIGRwbHlyOjpmaWx0ZXIoDQogICAgICBgU2lsbHkgQ29kZWAgJWluJSBjKCJQRFVDSzE0RSIsICJQRFVDSzE0TCIsICJQR1JFRzE0RSIsICJQR1JFRzE0TCIpDQogICAgKSAlPiUNCiAgICBkcGx5cjo6cmVuYW1lKA0KICAgICAgc2lsbHkgPSBgU2lsbHkgQ29kZWAsDQogICAgICBmaXNoX2lkID0gYEZpc2ggSURgLA0KICAgICAgc2V4ID0gU2V4DQogICAgKSAlPiUNCiAgICB0aWR5cjo6dW5pdGUoDQogICAgICBjb2wgPSAic2lsbHlfc291cmNlIiwNCiAgICAgIGMoc2lsbHksIGZpc2hfaWQpLA0KICAgICAgc2VwID0gIl8iLA0KICAgICAgcmVtb3ZlID0gVFJVRQ0KICAgICkgJT4lDQogICAgZHBseXI6OnNlbGVjdChzaWxseV9zb3VyY2UsIHNleCkNCikNCmBgYA0KDQojIyMgU2FsbW9uIEJpb2xvZ2ljYWwgRGF0YQ0KDQpPdG9saXRoIHJlYWQgZGF0YSBsaXZlcyBoZXJlLi4uDQpgYGB7cn0NCihvY2VhbmFrX29nIDwtIHJlYWRyOjpyZWFkX2NzdihmaWxlID0gIi4uL2RhdGEvRHVjayAyMDE0IGFuZCBHcmVnb3JpZWZmIDIwMTQgQUhSUCBTYWxtb24gQmlvbG9naWNhbCBEYXRhIDIwMjIwMzE4XzE2MDIwOS5jc3YiKSkNCmBgYA0KDQpNb2RpZnksIGZpbHRlciBmb3Igc2lsbHkgY29kZXMgb2YgaW50ZXJlc3QgYW5kIHRpc3N1ZSB0eXBlICJPdG9saXRoIg0KYGBge3J9DQooDQogIG9jZWFuYWsgPC0gb2NlYW5ha19vZyAlPiUNCiAgICBkcGx5cjo6ZmlsdGVyKA0KICAgICAgU0lMTFlfQ09ERSAlaW4lIGMoIlBEVUNLMTRFIiwgIlBEVUNLMTRMIiwgIlBHUkVHMTRFIiwgIlBHUkVHMTRMIiksDQogICAgICBUSVNTVUVfVFlQRSA9PSAiT3RvbGl0aCINCiAgICApICU+JQ0KICAgIGRwbHlyOjpyZW5hbWUoDQogICAgICBzaWxseSA9IFNJTExZX0NPREUsDQogICAgICBmaXNoX2lkID0gRklTSF9JRCwNCiAgICAgIHRpc3N1ZV90eXBlID0gVElTU1VFX1RZUEUsDQogICAgICBkd3BfYmFyY29kZSA9IEROQV9UUkFZX0NPREUsDQogICAgICBkd3Bfd2VsbCA9IEROQV9UUkFZX1dFTExfQ09ERSwNCiAgICAgIG90b2xpdGhfbWFya19wcmVzZW50ID0gT1RPTElUSF9NQVJLX1BSRVNFTlQNCiAgICApICU+JQ0KICAgIHRpZHlyOjp1bml0ZSgNCiAgICAgIGNvbCA9ICJzaWxseV9zb3VyY2UiLA0KICAgICAgYyhzaWxseSwgZmlzaF9pZCksDQogICAgICBzZXAgPSAiXyIsDQogICAgICByZW1vdmUgPSBGQUxTRQ0KICAgICkgJT4lDQogICAgZHBseXI6OnNlbGVjdCgNCiAgICAgIHNpbGx5X3NvdXJjZSwNCiAgICAgIG90b2xpdGhfbWFya19wcmVzZW50DQogICAgKQ0KKQ0KYGBgDQoNCiMjIEpvaW4NCg0KSm9pbiBhbGwgdGhyZWUgb2YgdGhlc2UgZGF0YSBzb3VyY2VzIGludG8gc29tZXRoaW5nIHVzZWZ1bCwgdGhlbiBmaWx0ZXIgYnkgb3VyIGNvbGxlY3Rpb25zIChEdWNrIGFuZCBHcmVnb3Jpb2ZmIDIwMTQpLCBub24tbWlzc2luZyB0aXNzdWUsIG5hdHVyYWwtb3JpZ2luLCBzcGxpdCBldmVubHkgYWNyb3NzIHNpbGx5IGNvZGVzIGFuZCBzZXhlcy4NCmBgYHtyfQ0KKGpvaW5fZHVja19ncmVnIDwtIGxva2lfdGlzc3VlICU+JSANCiAgIGRwbHlyOjpsZWZ0X2pvaW4obG9raV9maXNoLCBieSA9ICJzaWxseV9zb3VyY2UiKSAlPiUgDQogICBkcGx5cjo6bGVmdF9qb2luKG9jZWFuYWssIGJ5ID0gInNpbGx5X3NvdXJjZSIpDQopDQpgYGANCg0KIyMgRXh0cmFjdGlvbiBTZWxlY3Rpb24NCg0KRnJvbSBlYWNoIHNpbGx5LCBncmFiIHRoZSBmaXJzdCA5IGZpc2ggZnJvbSBlYWNoIHNleCB0aGF0IGFyZSBub3Qgb3RvbGl0aCBtYXJrZWQgKGkuZS4gbmF0dXJhbC1vcmlnaW4gZmlzaCkuIFRvdGFsIG9mIDE4IGZpc2ggcGVyIHNpbGx5LCAzNiBmaXNoIHBlciBzYW1wbGluZyB1bml0IChlYXJseSBhbmQgbGF0ZSBhcmUgc3RpbGwgb25lIHNhbXBsaW5nIHVuaXQpLg0KYGBge3J9DQooDQogIGV4dHJhY3Rpb25fZHVja19ncmVnIDwtIGpvaW5fZHVja19ncmVnICU+JQ0KICAgIGRwbHlyOjpmaWx0ZXIob3RvbGl0aF9tYXJrX3ByZXNlbnQgPT0gIk5PIiwNCiAgICAgICAgICAgICAgICAgIHNleCAhPSAiVSIpICU+JQ0KICAgIGRwbHlyOjpncm91cF9ieShzaWxseSwgc2V4KSAlPiUNCiAgICBkcGx5cjo6c2xpY2VfbWluKG9yZGVyX2J5ID0gZmlzaF9pZCwgbiA9IDkpICU+JQ0KICAgIGRwbHlyOjp1bmdyb3VwKCkgJT4lIA0KICAgIGRwbHlyOjphcnJhbmdlKHNpbGx5LCBmaXNoX2lkKSAlPiUgDQogICAgZHBseXI6OnNlbGVjdCgNCiAgICAgIHNpbGx5X3NvdXJjZSwNCiAgICAgIHNpbGx5LA0KICAgICAgZmlzaF9pZCwNCiAgICAgIGR3cF9iYXJjb2RlLA0KICAgICAgZHdwX3dlbGwsDQogICAgICB0aXNzdWVfdHlwZSwNCiAgICAgIHNleCwNCiAgICAgIG90b2xpdGhfbWFya19wcmVzZW50DQogICAgKQ0KKQ0KYGBgDQoNCldyaXRlIGl0IG91dCBmb3IgcG9zdGVyaXR5DQpgYGB7cn0NCnJlYWRyOjp3cml0ZV9jc3YoeCA9IGV4dHJhY3Rpb25fZHVja19ncmVnLCBmaWxlID0gIi4uL291dHB1dC9leHRyYWN0aW9uX3NlbGVjdGlvbl9QRFVDSzE0RV9QRFVDSzE0TF9QR1JFRzE0RV9QR1JFRzE0TC5jc3YiKQ0KYGBgDQoNCiMgRXJiIDE5OTENCg0KIyMgSW1wb3J0IERhdGENCg0KIyMjIExPS0kgVGlzc3VlIFRhYmxlDQoNCkRXUCBpbmZvcm1hdGlvbiBhbmQgdGlzc3VlIG1pc3NpbmcgZGF0YSBsaXZlcyBoZXJlLi4uDQpgYGB7cn0NCihsb2tpX3Rpc3N1ZV9vZyA8LSByZWFkcjo6cmVhZF9jc3YoZmlsZSA9ICIuLi9kYXRhL0xPS0lfdGlzc3VlX0dFTl9TQU1QTEVEX0ZJU0hfVElTU1VFLmNzdiIpKQ0KYGBgDQoNCk1vZGlmeSwgZmlsdGVyIGZvciBzaWxseSBjb2RlcyBvZiBpbnRlcmVzdCBhbmQgcmVtb3ZlIGFueSBmaXNoIHdpdGgga253b24gbWlzc2luZyB0aXNzdWVzDQpgYGB7cn0NCigNCiAgbG9raV90aXNzdWUgPC0gbG9raV90aXNzdWVfb2cgJT4lDQogICAgZHBseXI6OmZpbHRlcigNCiAgICAgIGBTaWxseSBDb2RlYCAlaW4lIGMoIlBFUkJFOTFUIiwgIlBFUkJMOTFUIiksDQogICAgICBQS19USVNTVUVfVFlQRSA9PSAiSGVhcnQiLA0KICAgICAgaXMubmEoSVNfTUlTU0lOR19QQUlSRURfREFUQV9FWElTVFMpLA0KICAgICAgaXMubmEoV0VMTF9IQVNfTU9SRV9USEFOX09ORV9TQU1QTEUpDQogICAgKSAlPiUNCiAgICBkcGx5cjo6cmVuYW1lKA0KICAgICAgc2lsbHkgPSBgU2lsbHkgQ29kZWAsDQogICAgICBmaXNoX2lkID0gRktfRklTSF9JRCwNCiAgICAgIHRpc3N1ZV90eXBlID0gUEtfVElTU1VFX1RZUEUsDQogICAgICBkd3BfYmFyY29kZSA9IEROQV9UUkFZX0NPREUsDQogICAgICBkd3Bfd2VsbCA9IEROQV9UUkFZX1dFTExfQ09ERQ0KICAgICkgJT4lDQogICAgdGlkeXI6OnVuaXRlKA0KICAgICAgY29sID0gInNpbGx5X3NvdXJjZSIsDQogICAgICBjKHNpbGx5LCBmaXNoX2lkKSwNCiAgICAgIHNlcCA9ICJfIiwNCiAgICAgIHJlbW92ZSA9IEZBTFNFDQogICAgKSAlPiUNCiAgICBkcGx5cjo6c2VsZWN0KA0KICAgICAgc2lsbHksDQogICAgICBmaXNoX2lkLA0KICAgICAgc2lsbHlfc291cmNlLA0KICAgICAgdGlzc3VlX3R5cGUsDQogICAgICBkd3BfYmFyY29kZSwNCiAgICAgIGR3cF93ZWxsDQogICAgKQ0KKQ0KYGBgDQoNCldhaXQsIHdoYXQ/IE5vIHRpc3N1ZXMgZm9yIFBFUkJMOTFULi4uLg0KDQpDb29sLCBubyBrbm93biBtaXNzaW5nLCBncmFiIGZpcnN0IDM2IGZyb20gUEVSQkU5MVQgdW50aWwgd2UgZmlndXJlIG91dCBQRVJCTDkxVC4NCg0KIyBFcmIgMjAxNw0KDQpOZWVkIHRoZSB0aXNzdWUgaW5mb3JtYXRpb24gZnJvbSAqTE9LSSogdGlzc3VlIHRhYmxlDQpOZWVkIHRoZSBzZXggYW5kIG90b2xpdGggZGF0YSBmcm9tICp3YXJlaG91c2UqDQoNClBpY2sgZmlzaCBhbmQgZm9ybWF0IGZvciBleHRyYWN0aW9uICh1c2UgUFdTIFBpbmsgYXMgYSB0ZW1wbGF0ZSkNCg0KIyMgSW1wb3J0IERhdGENCg0KIyMjIExPS0kgVGlzc3VlIFRhYmxlDQoNCkRXUCBpbmZvcm1hdGlvbiBhbmQgdGlzc3VlIG1pc3NpbmcgZGF0YSBsaXZlcyBoZXJlLi4uDQpgYGB7cn0NCihsb2tpX3Rpc3N1ZV9vZyA8LSByZWFkcjo6cmVhZF9jc3YoZmlsZSA9ICIuLi9kYXRhL0xPS0lfdGlzc3VlX0dFTl9TQU1QTEVEX0ZJU0hfVElTU1VFX1BFUkIxN18yMDIyMDMyMV8xNTA4MjEuY3N2IikpDQpgYGANCg0KTW9kaWZ5LCBmaWx0ZXIgZm9yIHNpbGx5IGNvZGVzIG9mIGludGVyZXN0IGFuZCByZW1vdmUgYW55IGZpc2ggd2l0aCBrbm93biBtaXNzaW5nIHRpc3N1ZXMNCmBgYHtyfQ0KZXJiXzIwMTdfb3RvX2Zpc2hfaWRzIDwtDQogIGRwbHlyOjpmaWx0ZXIoLmRhdGEgPSBsb2tpX3Rpc3N1ZV9vZywgUEtfVElTU1VFX1RZUEUgPT0gIk90b2xpdGgiKSAlPiUgcHVsbChGS19GSVNIX0lEKQ0KDQooDQogIGxva2lfdGlzc3VlIDwtIGxva2lfdGlzc3VlX29nICU+JQ0KICAgIGRwbHlyOjpmaWx0ZXIoDQogICAgICBGS19GSVNIX0lEICVpbiUgZXJiXzIwMTdfb3RvX2Zpc2hfaWRzLA0KICAgICAgUEtfVElTU1VFX1RZUEUgPT0gIkhlYXJ0LWJ1bGJ1cyBhcnRlcmlvc3VzIiwNCiAgICAgIElTX01JU1NJTkdfUEFJUkVEX0RBVEFfRVhJU1RTID09IDAsDQogICAgICBXRUxMX0hBU19NT1JFX1RIQU5fT05FX1NBTVBMRSA9PSAwDQogICAgKSAlPiUNCiAgICBkcGx5cjo6cmVuYW1lKA0KICAgICAgc2lsbHkgPSBTSUxMWV9DT0RFLA0KICAgICAgZmlzaF9pZCA9IEZLX0ZJU0hfSUQsDQogICAgICB0aXNzdWVfdHlwZSA9IFBLX1RJU1NVRV9UWVBFLA0KICAgICAgZHdwX2JhcmNvZGUgPSBETkFfVFJBWV9DT0RFLA0KICAgICAgZHdwX3dlbGwgPSBETkFfVFJBWV9XRUxMX0NPREUNCiAgICApICU+JQ0KICAgIHRpZHlyOjp1bml0ZSgNCiAgICAgIGNvbCA9ICJzaWxseV9zb3VyY2UiLA0KICAgICAgYyhzaWxseSwgZmlzaF9pZCksDQogICAgICBzZXAgPSAiXyIsDQogICAgICByZW1vdmUgPSBGQUxTRQ0KICAgICkgJT4lDQogICAgZHBseXI6OnNlbGVjdCgNCiAgICAgIHNpbGx5LA0KICAgICAgZmlzaF9pZCwNCiAgICAgIHNpbGx5X3NvdXJjZSwNCiAgICAgIHRpc3N1ZV90eXBlLA0KICAgICAgZHdwX2JhcmNvZGUsDQogICAgICBkd3Bfd2VsbA0KICAgICkNCikNCmBgYA0KDQojIyMgU2FsbW9uIEJpb2xvZ2ljYWwgRGF0YQ0KDQpTZXggYW5kIG90b2xpdGggcmVhZCBkYXRhIGxpdmVzIGhlcmUuLi4NCmBgYHtyfQ0KKG9jZWFuYWtfb2cgPC0gcmVhZHI6OnJlYWRfY3N2KGZpbGUgPSAiLi4vZGF0YS9FcmIgMjAxNyBBSFJQIFNhbG1vbiBCaW9sb2dpY2FsIERhdGEgMjAyMjAzMjFfMTUxMDI3LmNzdiIpKQ0KYGBgDQoNCk1vZGlmeSwgZmlsdGVyIGZvciBzaWxseSBjb2RlcyBvZiBpbnRlcmVzdCBhbmQgdGlzc3VlIHR5cGUgIkhlYXJ0LWJ1bGJ1cyBhcnRlcmlvc3VzIg0KYGBge3J9DQooDQogIG9jZWFuYWsgPC0gb2NlYW5ha19vZyAlPiUNCiAgICBkcGx5cjo6ZmlsdGVyKA0KICAgICAgVElTU1VFX1RZUEUgPT0gIkhlYXJ0LWJ1bGJ1cyBhcnRlcmlvc3VzIg0KICAgICkgJT4lDQogICAgZHBseXI6OnJlbmFtZSgNCiAgICAgIHNpbGx5ID0gU0lMTFlfQ09ERSwNCiAgICAgIGZpc2hfaWQgPSBGSVNIX0lELA0KICAgICAgdGlzc3VlX3R5cGUgPSBUSVNTVUVfVFlQRSwNCiAgICAgIGR3cF9iYXJjb2RlID0gRE5BX1RSQVlfQ09ERSwNCiAgICAgIGR3cF93ZWxsID0gRE5BX1RSQVlfV0VMTF9DT0RFLA0KICAgICAgc2FtcGxlX2RhdGUgPSBTQU1QTEVfREFURSwNCiAgICAgIHNleCA9IFNFWCwNCiAgICAgIG90b2xpdGhfbWFya19wcmVzZW50ID0gT1RPTElUSF9NQVJLX1BSRVNFTlQNCiAgICApICU+JQ0KICAgIGRwbHlyOjptdXRhdGUoc2FtcGxlX2RhdGUgPSBsdWJyaWRhdGU6OnltZChzYW1wbGVfZGF0ZSkpICU+JSANCiAgICB0aWR5cjo6dW5pdGUoDQogICAgICBjb2wgPSAic2lsbHlfc291cmNlIiwNCiAgICAgIGMoc2lsbHksIGZpc2hfaWQpLA0KICAgICAgc2VwID0gIl8iLA0KICAgICAgcmVtb3ZlID0gRkFMU0UNCiAgICApICU+JQ0KICAgIGRwbHlyOjpzZWxlY3QoDQogICAgICBzaWxseV9zb3VyY2UsDQogICAgICBzYW1wbGVfZGF0ZSwNCiAgICAgIHNleCwNCiAgICAgIG90b2xpdGhfbWFya19wcmVzZW50DQogICAgKQ0KKQ0KYGBgDQoNCiMjIEpvaW4NCg0KSm9pbiBhbGwgdHdvIG9mIHRoZXNlIGRhdGEgc291cmNlcyBpbnRvIHNvbWV0aGluZyB1c2VmdWwsIHRoZW4gZmlsdGVyIGJ5IG91ciBjb2xsZWN0aW9ucyAoRHVjayBhbmQgR3JlZ29yaW9mZiAyMDE0KSwgbm9uLW1pc3NpbmcgdGlzc3VlLCBuYXR1cmFsLW9yaWdpbiwgc3BsaXQgZXZlbmx5IGFjcm9zcyBzaWxseSBjb2RlcyBhbmQgc2V4ZXMuDQpgYGB7cn0NCihqb2luX2R1Y2tfZ3JlZyA8LSBsb2tpX3Rpc3N1ZSAlPiUgDQogICBkcGx5cjo6bGVmdF9qb2luKG9jZWFuYWssIGJ5ID0gInNpbGx5X3NvdXJjZSIpDQopDQpgYGANCg0KIyMgRXh0cmFjdGlvbiBTZWxlY3Rpb24NCg0KRnJvbSBlYWNoIHNpbGx5LCBncmFiIHRoZSBmaXJzdCA5IGZpc2ggZnJvbSBlYWNoIHNleCB0aGF0IGFyZSBub3Qgb3RvbGl0aCBtYXJrZWQgKGkuZS4gbmF0dXJhbC1vcmlnaW4gZmlzaCkuIFRvdGFsIG9mIDE4IGZpc2ggcGVyIHNpbGx5LCAzNiBmaXNoIHBlciBzYW1wbGluZyB1bml0IChlYXJseSBhbmQgbGF0ZSBhcmUgc3RpbGwgb25lIHNhbXBsaW5nIHVuaXQpLg0KYGBge3J9DQooDQogIGV4dHJhY3Rpb25fZXJiXzIwMTcgPC0gam9pbl9kdWNrX2dyZWcgJT4lDQogICAgZHBseXI6OmZpbHRlcihvdG9saXRoX21hcmtfcHJlc2VudCA9PSAiTk8iLA0KICAgICAgICAgICAgICAgICAgc2V4ICE9ICJVIikgJT4lDQogICAgZHBseXI6Omdyb3VwX2J5KHNpbGx5LCBzZXgpICU+JQ0KICAgIGRwbHlyOjpzbGljZV9zYW1wbGUobiA9IDE4KSAlPiUNCiAgICBkcGx5cjo6dW5ncm91cCgpICU+JSANCiAgICBkcGx5cjo6YXJyYW5nZShzaWxseSwgZmlzaF9pZCkgJT4lIA0KICAgIGRwbHlyOjpzZWxlY3QoDQogICAgICBzaWxseV9zb3VyY2UsDQogICAgICBzaWxseSwNCiAgICAgIGZpc2hfaWQsDQogICAgICBkd3BfYmFyY29kZSwNCiAgICAgIGR3cF93ZWxsLA0KICAgICAgdGlzc3VlX3R5cGUsDQogICAgICBzYW1wbGVfZGF0ZSwNCiAgICAgIHNleCwNCiAgICAgIG90b2xpdGhfbWFya19wcmVzZW50DQogICAgKQ0KKQ0KYGBgDQoNCldyaXRlIGl0IG91dCBmb3IgcG9zdGVyaXR5DQpgYGB7cn0NCnJlYWRyOjp3cml0ZV9jc3YoeCA9IGV4dHJhY3Rpb25fZXJiXzIwMTcsIGZpbGUgPSAiLi4vb3V0cHV0L2V4dHJhY3Rpb25fc2VsZWN0aW9uX1BFUkIxNy5jc3YiKQ0KYGBgDQoNCiMgRHVjayBSaXZlciAyMDEzDQoNCkdvdCBzZXggZGF0YSBmcm9tIFdlaSBvbiAzLzIxLzIyDQoNCk5lZWQgdGhlIHRpc3N1ZSBpbmZvcm1hdGlvbiBmcm9tICpMT0tJKiB0aXNzdWUgdGFibGUNCk5lZWQgdGhlIHNleCBkYXRhIGZyb20gKkxPS0kqIGZpc2ggdGFibGUNCk5lZWQgdGhlIG90b2xpdGggZGF0YSBmcm9tICp3YXJlaG91c2UqDQoNClBpY2sgZmlzaCBhbmQgZm9ybWF0IGZvciBleHRyYWN0aW9uICh1c2UgUFdTIFBpbmsgYXMgYSB0ZW1wbGF0ZSkNCg0KIyMgSW1wb3J0IERhdGENCg0KIyMjIExPS0kgVGlzc3VlIFRhYmxlDQoNCkRXUCBpbmZvcm1hdGlvbiBhbmQgdGlzc3VlIG1pc3NpbmcgZGF0YSBsaXZlcyBoZXJlLi4uDQpgYGB7cn0NCihsb2tpX3Rpc3N1ZV9vZyA8LSByZWFkcjo6cmVhZF9jc3YoZmlsZSA9ICIuLi9kYXRhL0xPS0lfdGlzc3VlX0dFTl9TQU1QTEVEX0ZJU0hfVElTU1VFX1BEVUNLMTNfMjAyMjAzMjJfMTAzNTQzLmNzdiIpKQ0KYGBgDQoNCk1vZGlmeSwgZmlsdGVyIGZvciBzaWxseSBjb2RlcyBvZiBpbnRlcmVzdCBhbmQgcmVtb3ZlIGFueSBmaXNoIHdpdGgga253b24gbWlzc2luZyB0aXNzdWVzDQpgYGB7cn0NCigNCiAgbG9raV90aXNzdWUgPC0gbG9raV90aXNzdWVfb2cgJT4lDQogICAgZHBseXI6OmZpbHRlcigNCiAgICAgIFNJTExZX0NPREUgJWluJSBjKCJQRFVDSzEzIiksDQogICAgICBQS19USVNTVUVfVFlQRSA9PSAiQXhpbGxhcnkgUHJvY2VzcyIsDQogICAgICBpcy5uYShJU19NSVNTSU5HX1BBSVJFRF9EQVRBX0VYSVNUUyksDQogICAgICBpcy5uYShXRUxMX0hBU19NT1JFX1RIQU5fT05FX1NBTVBMRSkNCiAgICApICU+JQ0KICAgIGRwbHlyOjpyZW5hbWUoDQogICAgICBzaWxseSA9IFNJTExZX0NPREUsDQogICAgICBmaXNoX2lkID0gRktfRklTSF9JRCwNCiAgICAgIHRpc3N1ZV90eXBlID0gUEtfVElTU1VFX1RZUEUsDQogICAgICBkd3BfYmFyY29kZSA9IEROQV9UUkFZX0NPREUsDQogICAgICBkd3Bfd2VsbCA9IEROQV9UUkFZX1dFTExfQ09ERQ0KICAgICkgJT4lDQogICAgdGlkeXI6OnVuaXRlKA0KICAgICAgY29sID0gInNpbGx5X3NvdXJjZSIsDQogICAgICBjKHNpbGx5LCBmaXNoX2lkKSwNCiAgICAgIHNlcCA9ICJfIiwNCiAgICAgIHJlbW92ZSA9IEZBTFNFDQogICAgKSAlPiUNCiAgICBkcGx5cjo6c2VsZWN0KA0KICAgICAgc2lsbHksDQogICAgICBmaXNoX2lkLA0KICAgICAgc2lsbHlfc291cmNlLA0KICAgICAgdGlzc3VlX3R5cGUsDQogICAgICBkd3BfYmFyY29kZSwNCiAgICAgIGR3cF93ZWxsDQogICAgKQ0KKQ0KYGBgDQoNCiMjIyBMT0tJIEZpc2ggVGFibGUNCg0KU2V4IGRhdGEgbGl2ZXMgaGVyZS4uLg0KYGBge3J9DQoobG9raV9maXNoX29nIDwtIHJlYWRyOjpyZWFkX2NzdihmaWxlID0gIi4uL2RhdGEvTE9LSV90aXNzdWVfR0VOX1NBTVBMRURfRklTSF9QRFVDSzEzXzIwMjIwMzIyXzEwNDY0OC5jc3YiKSkNCmBgYA0KDQpNb2RpZnksIGZpbHRlciBmb3Igc2lsbHkgY29kZXMgb2YgaW50ZXJlc3QNCmBgYHtyfQ0KKA0KICBsb2tpX2Zpc2ggPC0gbG9raV9maXNoX29nICU+JQ0KICAgIGRwbHlyOjpmaWx0ZXIoDQogICAgICBTSUxMWV9DT0RFID09ICJQRFVDSzEzIg0KICAgICkgJT4lDQogICAgZHBseXI6OnJlbmFtZSgNCiAgICAgIHNpbGx5ID0gU0lMTFlfQ09ERSwNCiAgICAgIGZpc2hfaWQgPSBGSVNIX0lELA0KICAgICAgc2V4ID0gU0VYDQogICAgKSAlPiUNCiAgICB0aWR5cjo6dW5pdGUoDQogICAgICBjb2wgPSAic2lsbHlfc291cmNlIiwNCiAgICAgIGMoc2lsbHksIGZpc2hfaWQpLA0KICAgICAgc2VwID0gIl8iLA0KICAgICAgcmVtb3ZlID0gVFJVRQ0KICAgICkgJT4lDQogICAgZHBseXI6OnNlbGVjdChzaWxseV9zb3VyY2UsIHNleCkNCikNCmBgYA0KDQojIyMgU2FsbW9uIEJpb2xvZ2ljYWwgRGF0YQ0KDQpPdG9saXRoIHJlYWQgZGF0YSBsaXZlcyBoZXJlLi4uDQpgYGB7cn0NCihvY2VhbmFrX29nIDwtIHJlYWRyOjpyZWFkX2NzdihmaWxlID0gIi4uL2RhdGEvRHVjayAyMDEzIEFIUlAgU2FsbW9uIEJpb2xvZ2ljYWwgRGF0YSAyMDIyMDMyMl8xMDM2MTEuY3N2IikpDQpgYGANCg0KYGBge3J9DQpvY2VhbmFrX29nICU+JSANCiAgY291bnQoU0lMTFlfQ09ERSwgU0FNUExFX0RBVEUpDQpgYGANCg0KTW9kaWZ5LCBmaWx0ZXIgZm9yIHNpbGx5IGNvZGVzIG9mIGludGVyZXN0IGFuZCB0aXNzdWUgdHlwZSAiT3RvbGl0aCINCmBgYHtyfQ0KKA0KICBvY2VhbmFrIDwtIG9jZWFuYWtfb2cgJT4lDQogICAgZHBseXI6OmZpbHRlcigNCiAgICAgIFNJTExZX0NPREUgPT0gIlBEVUNLMTMiLA0KICAgICAgVElTU1VFX1RZUEUgPT0gIk90b2xpdGgiDQogICAgKSAlPiUNCiAgICBkcGx5cjo6cmVuYW1lKA0KICAgICAgc2lsbHkgPSBTSUxMWV9DT0RFLA0KICAgICAgZmlzaF9pZCA9IEZJU0hfSUQsDQogICAgICB0aXNzdWVfdHlwZSA9IFRJU1NVRV9UWVBFLA0KICAgICAgZHdwX2JhcmNvZGUgPSBETkFfVFJBWV9DT0RFLA0KICAgICAgZHdwX3dlbGwgPSBETkFfVFJBWV9XRUxMX0NPREUsDQogICAgICBvdG9saXRoX21hcmtfcHJlc2VudCA9IE9UT0xJVEhfTUFSS19QUkVTRU5UDQogICAgKSAlPiUNCiAgICB0aWR5cjo6dW5pdGUoDQogICAgICBjb2wgPSAic2lsbHlfc291cmNlIiwNCiAgICAgIGMoc2lsbHksIGZpc2hfaWQpLA0KICAgICAgc2VwID0gIl8iLA0KICAgICAgcmVtb3ZlID0gRkFMU0UNCiAgICApICU+JQ0KICAgIGRwbHlyOjpzZWxlY3QoDQogICAgICBzaWxseV9zb3VyY2UsDQogICAgICBvdG9saXRoX21hcmtfcHJlc2VudA0KICAgICkNCikNCmBgYA0KDQpgYGB7cn0NCm9jZWFuYWsgJT4lIA0KICBjb3VudChvdG9saXRoX21hcmtfcHJlc2VudCkNCmBgYA0KDQoNCiMjIEpvaW4NCg0KSm9pbiBhbGwgdGhyZWUgb2YgdGhlc2UgZGF0YSBzb3VyY2VzIGludG8gc29tZXRoaW5nIHVzZWZ1bCwgdGhlbiBmaWx0ZXIgYnkgb3VyIGNvbGxlY3Rpb25zIChEdWNrIDEzKSwgbm9uLW1pc3NpbmcgdGlzc3VlLCBuYXR1cmFsLW9yaWdpbiwgc3BsaXQgZXZlbmx5IGFjcm9zcyBzaWxseSBjb2RlcyBhbmQgc2V4ZXMuDQpgYGB7cn0NCihqb2luX2R1Y2tfMjAxMyA8LSBsb2tpX3Rpc3N1ZSAlPiUgDQogICBkcGx5cjo6bGVmdF9qb2luKGxva2lfZmlzaCwgYnkgPSAic2lsbHlfc291cmNlIikgJT4lIA0KICAgZHBseXI6OmxlZnRfam9pbihvY2VhbmFrLCBieSA9ICJzaWxseV9zb3VyY2UiKQ0KKQ0KYGBgDQoNCiMjIEV4dHJhY3Rpb24gU2VsZWN0aW9uDQoNCkZyb20gZWFjaCBzaWxseSwgZ3JhYiB0aGUgZmlyc3QgMTggZmlzaCBmcm9tIGVhY2ggc2V4IHRoYXQgYXJlIG5vdCBvdG9saXRoIG1hcmtlZCAoaS5lLiBuYXR1cmFsLW9yaWdpbiBmaXNoKS4gVG90YWwgb2YgMzYgZmlzaCBwZXIgc2lsbHksIDM2IGZpc2ggcGVyIHNhbXBsaW5nIHVuaXQuDQpgYGB7cn0NCigNCiAgZXh0cmFjdGlvbl9kdWNrXzIwMTMgPC0gam9pbl9kdWNrXzIwMTMgJT4lDQogICAgZHBseXI6OmZpbHRlcihvdG9saXRoX21hcmtfcHJlc2VudCA9PSAiTk8iLA0KICAgICAgICAgICAgICAgICAgc2V4ICE9ICJVIikgJT4lDQogICAgZHBseXI6Omdyb3VwX2J5KHNpbGx5LCBzZXgpICU+JQ0KICAgIGRwbHlyOjpzbGljZV9taW4ob3JkZXJfYnkgPSBmaXNoX2lkLCBuID0gMTgpICU+JQ0KICAgIGRwbHlyOjp1bmdyb3VwKCkgJT4lIA0KICAgIGRwbHlyOjphcnJhbmdlKHNpbGx5LCBmaXNoX2lkKSAlPiUgDQogICAgZHBseXI6OnNlbGVjdCgNCiAgICAgIHNpbGx5X3NvdXJjZSwNCiAgICAgIHNpbGx5LA0KICAgICAgZmlzaF9pZCwNCiAgICAgIGR3cF9iYXJjb2RlLA0KICAgICAgZHdwX3dlbGwsDQogICAgICB0aXNzdWVfdHlwZSwNCiAgICAgIHNleCwNCiAgICAgIG90b2xpdGhfbWFya19wcmVzZW50DQogICAgKQ0KKQ0KYGBgDQoNCldyaXRlIGl0IG91dCBmb3IgcG9zdGVyaXR5DQpgYGB7cn0NCnJlYWRyOjp3cml0ZV9jc3YoeCA9IGV4dHJhY3Rpb25fZHVja18yMDEzLCBmaWxlID0gIi4uL291dHB1dC9leHRyYWN0aW9uX3NlbGVjdGlvbl9QRFVDSzEzLmNzdiIpDQpgYGANCg0KIyBTdG9ja2RhbGUgMjAxNg0KDQpOZWVkIGhhdGNoZXJ5IHN0cmF5cyBhbmQgbmF0dXJhbC1vcmlnaW4gaG9taW5nIGZpc2ggKGkuZS4gdGhvc2Ugd2l0aCBuYXR1cmFsLW9yaWdpbiBwYXJlbnRzKQ0KDQojIyBOYXR1cmFsLW9yaWdpbiBIb21pbmcNCg0KU3BsaXQgYnkgc2V4LCBzYW1wbGVkIHRocm91Z2hvdXQgdGhlIHNlYXNvbg0KDQojIyMgSW1wb3J0IERhdGENCg0KQmFkIHByYWN0aWNlLCBidXQgSSdtIGdvaW5nIHRvIGdyYWIgb3V0cHV0IGRhdGEgZnJvbSBQV1MtUGluay1QYXJlbnRhZ2UNCmBgYHtyfQ0KKA0KICBhbGxfc3RyZWFtc19wYXJlbnRzX3BhaXJlZF8xNF8xNl9jcm9zcyA8LQ0KICAgIHJlYWRyOjpyZWFkX2NzdihmaWxlID0gIi4uLy4uL1BXUyBQaW5rL0dpdEh1Yi1QV1MtUGluay1QYXJlbnRhZ2UvU3RvY2tkYWxlX0hvZ2FuX0dpbG1vdXJfUGFkZHlfRXJiL2FsbF9zdHJlYW1zX3BhcmVudHNfcGFpcmVkXzE0XzE2X2Nyb3NzLmNzdiIpDQopDQoNCigNCiAgYWxsX3N0cmVhbXNfcGFyZW50c19wYWlyZWRfMTRfMTYgPC0NCiAgICByZWFkcjo6cmVhZF9jc3YoZmlsZSA9ICIuLi8uLi9QV1MgUGluay9HaXRIdWItUFdTLVBpbmstUGFyZW50YWdlL1N0b2NrZGFsZV9Ib2dhbl9HaWxtb3VyX1BhZGR5X0VyYi9hbGxfc3RyZWFtc19wYXJlbnRzX3BhaXJlZF8xNF8xNi5jc3YiKQ0KKQ0KYGBgDQoNCiMjIyBDaG9vc2UgZnJvbSBOTiBjcm9zc2VzDQoNCkZpbHRlciBmb3IgU3RvY2tkYWxlIGFuZCBvbmx5IA0KYGBge3J9DQpzdG9ja2RhbGVfMjAxNl9uYXR1cmFsX3NlbGVjdGlvbl9OTl9jcm9zcyA8LSBhbGxfc3RyZWFtc19wYXJlbnRzX3BhaXJlZF8xNF8xNl9jcm9zcyAlPiUgDQogIGRwbHlyOjpmaWx0ZXIoc3RyZWFtX29mZiA9PSBzdHJlYW1fc2lyZSwNCiAgICAgICAgICAgICAgICBzdHJlYW1fb2ZmID09ICJTdG9ja2RhbGUiLA0KICAgICAgICAgICAgICAgIG9yaWdpbl9zaXJlID09IG9yaWdpbl9kYW0sDQogICAgICAgICAgICAgICAgb3JpZ2luX3NpcmUgPT0gIk5hdHVyYWwiKSAlPiUgDQogIGRwbHlyOjpncm91cF9ieShtYXRpbmdfaWQpICU+JSANCiAgZHBseXI6OnNsaWNlX3NhbXBsZShuID0gMSwgcmVwbGFjZSA9IEZBTFNFKSAlPiUgDQogIGRwbHlyOjpncm91cF9ieShwYXJlbnRfaWRfc2lyZSkgJT4lIA0KICBkcGx5cjo6c2xpY2Vfc2FtcGxlKG4gPSAxLCByZXBsYWNlID0gRkFMU0UpICU+JSANCiAgZHBseXI6Omdyb3VwX2J5KHBhcmVudF9pZF9kYW0pICU+JSANCiAgZHBseXI6OnNsaWNlX3NhbXBsZShuID0gMSwgcmVwbGFjZSA9IEZBTFNFKSAlPiUgDQogIGRwbHlyOjp1bmdyb3VwKCkgDQoNCnN0b2NrZGFsZV8yMDE2X25hdHVyYWxfc2VsZWN0aW9uX05OX2Nyb3NzICU+JSANCiAgZHBseXI6OmNvdW50KHNleF9vZmYpDQpgYGANCg0KTW9kaWZ5IGZvciBleHRyYWN0aW9uIGZvcm1hdA0KYGBge3J9DQooDQogIHN0b2NrZGFsZV8yMDE2X25hdHVyYWxfc2VsZWN0aW9uX05OX2Nyb3NzIDwtDQogICAgc3RvY2tkYWxlXzIwMTZfbmF0dXJhbF9zZWxlY3Rpb25fTk5fY3Jvc3MgJT4lDQogICAgZHBseXI6OnJlbmFtZSgNCiAgICAgIHNpbGx5ID0gc2lsbHlfb2ZmLA0KICAgICAgZmlzaF9pZCA9IGZpc2hfaWRfb2ZmLA0KICAgICAgZHdwX2JhcmNvZGUgPSBkbmFfdHJheV9jb2RlX29mZiwNCiAgICAgIGR3cF93ZWxsID0gZG5hX3RyYXlfd2VsbF9jb2RlX29mZiwNCiAgICAgIHNhbXBsZV9kYXRlID0gZGF0ZV9vZmYsDQogICAgICBzZXggPSBzZXhfb2ZmLA0KICAgICAgb3RvbGl0aF9tYXJrX3ByZXNlbnQgPSBvdG9saXRoX21hcmtfcHJlc2VudF9vZmYNCiAgICApICU+JQ0KICAgIGRwbHlyOjptdXRhdGUodGlzc3VlX3R5cGUgPSAiSGVhcnQtYnVsYnVzIGFydGVyaW9zdXMiKSAlPiUNCiAgICB0aWR5cjo6dW5pdGUoDQogICAgICBjb2wgPSAic2lsbHlfc291cmNlIiwNCiAgICAgIGMoc2lsbHksIGZpc2hfaWQpLA0KICAgICAgc2VwID0gIl8iLA0KICAgICAgcmVtb3ZlID0gRkFMU0UNCiAgICApICU+JQ0KICAgIGRwbHlyOjphcnJhbmdlKHNpbGx5LCBmaXNoX2lkKSAlPiUNCiAgICBkcGx5cjo6c2VsZWN0KA0KICAgICAgc2lsbHlfc291cmNlLA0KICAgICAgc2lsbHksDQogICAgICBmaXNoX2lkLA0KICAgICAgZHdwX2JhcmNvZGUsDQogICAgICBkd3Bfd2VsbCwNCiAgICAgIHRpc3N1ZV90eXBlLA0KICAgICAgc2FtcGxlX2RhdGUsDQogICAgICBzZXgsDQogICAgICBvdG9saXRoX21hcmtfcHJlc2VudA0KICAgICkNCikNCmBgYA0KDQpTdGlsbCBuZWVkIDEgbW9yZSBNYWxlLCBwaWNrIGZyb20gZHlhZCBkYXRhDQoNCiMjIyBDaG9zZSBmcm9tIE4gZHlhZHMNCg0KYGBge3J9DQooDQogIHN0b2NrZGFsZV8yMDE2X25hdHVyYWxfc2VsZWN0aW9uX05fZHlhZCA8LQ0KICAgIGFsbF9zdHJlYW1zX3BhcmVudHNfcGFpcmVkXzE0XzE2ICU+JQ0KICAgIGRwbHlyOjpyZW5hbWUoDQogICAgICBzaWxseSA9IHNpbGx5X29mZiwNCiAgICAgIGZpc2hfaWQgPSBmaXNoX2lkX29mZiwNCiAgICAgIGR3cF9iYXJjb2RlID0gZG5hX3RyYXlfY29kZV9vZmYsDQogICAgICBkd3Bfd2VsbCA9IGRuYV90cmF5X3dlbGxfY29kZV9vZmYsDQogICAgICBzYW1wbGVfZGF0ZSA9IGRhdGVfb2ZmLA0KICAgICAgc2V4ID0gc2V4X29mZiwNCiAgICAgIG90b2xpdGhfbWFya19wcmVzZW50ID0gb3RvbGl0aF9tYXJrX3ByZXNlbnRfb2ZmDQogICAgKSAlPiUNCiAgICBkcGx5cjo6bXV0YXRlKHRpc3N1ZV90eXBlID0gIkhlYXJ0LWJ1bGJ1cyBhcnRlcmlvc3VzIikgJT4lDQogICAgdGlkeXI6OnVuaXRlKA0KICAgICAgY29sID0gInNpbGx5X3NvdXJjZSIsDQogICAgICBjKHNpbGx5LCBmaXNoX2lkKSwNCiAgICAgIHNlcCA9ICJfIiwNCiAgICAgIHJlbW92ZSA9IEZBTFNFDQogICAgKSAlPiUNCiAgICBkcGx5cjo6ZmlsdGVyKA0KICAgICAgc3RyZWFtX29mZiA9PSBzdHJlYW1fcGFyLA0KICAgICAgc3RyZWFtX29mZiA9PSAiU3RvY2tkYWxlIiwNCiAgICAgIG9yaWdpbl9wYXIgPT0gIk5hdHVyYWwiLA0KICAgICAgc2V4ID09ICJNYWxlIiwNCiAgICAgICEoDQogICAgICAgIHNpbGx5X3NvdXJjZSAlaW4lIHN0b2NrZGFsZV8yMDE2X25hdHVyYWxfc2VsZWN0aW9uX05OX2Nyb3NzJHNpbGx5X3NvdXJjZQ0KICAgICAgKSwNCiAgICAgICEoDQogICAgICAgIHBhcmVudF9pZCAlaW4lIGFsbF9zdHJlYW1zX3BhcmVudHNfcGFpcmVkXzE0XzE2X2Nyb3NzJHBhcmVudF9pZF9kYW0NCiAgICAgICksDQogICAgICAhKA0KICAgICAgICBwYXJlbnRfaWQgJWluJSBhbGxfc3RyZWFtc19wYXJlbnRzX3BhaXJlZF8xNF8xNl9jcm9zcyRwYXJlbnRfaWRfc2lyZQ0KICAgICAgKQ0KICAgICkgJT4lDQogICAgZHBseXI6Omdyb3VwX2J5KHNleCkgJT4lDQogICAgZHBseXI6OnNsaWNlX3NhbXBsZShuID0gMSwgcmVwbGFjZSA9IEZBTFNFKSAlPiUNCiAgICBkcGx5cjo6dW5ncm91cCgpICU+JSANCiAgICBkcGx5cjo6YXJyYW5nZShzaWxseSwgZmlzaF9pZCkgJT4lDQogICAgZHBseXI6OnNlbGVjdCgNCiAgICAgIHNpbGx5X3NvdXJjZSwNCiAgICAgIHNpbGx5LA0KICAgICAgZmlzaF9pZCwNCiAgICAgIGR3cF9iYXJjb2RlLA0KICAgICAgZHdwX3dlbGwsDQogICAgICB0aXNzdWVfdHlwZSwNCiAgICAgIHNhbXBsZV9kYXRlLA0KICAgICAgc2V4LA0KICAgICAgb3RvbGl0aF9tYXJrX3ByZXNlbnQNCiAgICApDQopDQoNCnN0b2NrZGFsZV8yMDE2X25hdHVyYWxfc2VsZWN0aW9uX05fZHlhZCAlPiUNCiAgZHBseXI6OmNvdW50KHNleCkNCmBgYA0KDQojIyMgRXh0cmFjdGlvbiBTZWxlY3Rpb24NCg0KQmluZCB0b2dldGhlciwgbWFrZSBzdXJlIG5vIGR1cGxpY2F0ZXMNCmBgYHtyfQ0KKA0KICBleHRyYWN0aW9uX1BTVE9DSzE2X25hdHVyYWwgPC0NCiAgICBkcGx5cjo6YmluZF9yb3dzKA0KICAgICAgc3RvY2tkYWxlXzIwMTZfbmF0dXJhbF9zZWxlY3Rpb25fTk5fY3Jvc3MsDQogICAgICBzdG9ja2RhbGVfMjAxNl9uYXR1cmFsX3NlbGVjdGlvbl9OX2R5YWQNCiAgICApICU+JQ0KICAgIGRwbHlyOjphcnJhbmdlKHNpbGx5LCBmaXNoX2lkKSAlPiUgDQogICAgZHBseXI6OmRpc3RpbmN0KCkNCikNCmBgYA0KDQpEb3VibGUgY2hlY2sgc2FtcGxlIHNpemVzDQpgYGB7cn0NCmV4dHJhY3Rpb25fUFNUT0NLMTZfbmF0dXJhbCAlPiUgDQogIGRwbHlyOjpjb3VudChzaWxseSkNCg0KZXh0cmFjdGlvbl9QU1RPQ0sxNl9uYXR1cmFsICU+JSANCiAgZHBseXI6OmNvdW50KHNpbGx5LCBzZXgpDQpgYGANCg0KV3JpdGUgaXQgb3V0IGZvciBwb3N0ZXJpdHkNCmBgYHtyfQ0KcmVhZHI6OndyaXRlX2Nzdih4ID0gZXh0cmFjdGlvbl9QU1RPQ0sxNl9uYXR1cmFsLCBmaWxlID0gIi4uL291dHB1dC9leHRyYWN0aW9uX1BTVE9DSzE2X25hdHVyYWwuY3N2IikNCmBgYA0KDQojIFN0b2NrZGFsZSAyMDE1DQoNCk5lZWQgaGF0Y2hlcnkgc3RyYXlzIGFuZCBuYXR1cmFsLW9yaWdpbiBob21pbmcgZmlzaCAoaS5lLiB0aG9zZSB3aXRoIG5hdHVyYWwtb3JpZ2luIHBhcmVudHMpDQoNCiMjIE5hdHVyYWwtb3JpZ2luIEhvbWluZw0KDQpTcGxpdCBieSBzZXgsIHNhbXBsZWQgdGhyb3VnaG91dCB0aGUgc2Vhc29uDQoNCiMjIyBJbXBvcnQgRGF0YQ0KDQpCYWQgcHJhY3RpY2UsIGJ1dCBJJ20gZ29pbmcgdG8gZ3JhYiBvdXRwdXQgZGF0YSBmcm9tIFBXUy1QaW5rLVBhcmVudGFnZQ0KYGBge3J9DQooDQogIHN0b2NrZGFsZV9wYXJlbnRzX3BhaXJlZF8xM18xNSA8LQ0KICAgIHJlYWRyOjpyZWFkX2NzdihmaWxlID0gIi4uLy4uL1BXUyBQaW5rL0dpdEh1Yi1QV1MtUGluay1QYXJlbnRhZ2UvU3RvY2tkYWxlL3N0b2NrX3BhcmVudHNfcGFpcmVkXzEzXzE1LmNzdiIpDQopDQpgYGANCg0KIyMjIENob29zZSBmcm9tIE5OIGNyb3NzZXMNCg0KVGhlcmUgYXJlIGlzIG5vIHRyaWFkIGRhdGEgZm9yIHRoZSAyMDEzLzIwMTUgcGVkaWdyZWVzDQoNCiMjIyBDaG9zZSBmcm9tIE4gZHlhZHMNCg0KYGBge3J9DQooDQogIHN0b2NrZGFsZV8yMDE1X25hdHVyYWxfc2VsZWN0aW9uX05fZHlhZCA8LQ0KICAgIHN0b2NrZGFsZV9wYXJlbnRzX3BhaXJlZF8xM18xNSAlPiUNCiAgICBkcGx5cjo6cmVuYW1lKA0KICAgICAgc2lsbHkgPSBTSUxMWS5vZmYsDQogICAgICBmaXNoX2lkID0gIkZpc2ggSUQub2ZmIiwNCiAgICAgIGR3cF9iYXJjb2RlID0gIkROQSBUcmF5IENvZGUub2ZmIiwNCiAgICAgIGR3cF93ZWxsID0gIkROQSBUcmF5IFdlbGwgQ29kZS5vZmYiLA0KICAgICAgc2FtcGxlX2RhdGUgPSBkYXRlLm9mZiwNCiAgICAgIHNleCA9IFNFWC5vZmYsDQogICAgICBvdG9saXRoX21hcmtfcHJlc2VudCA9ICJPdG9saXRoIE1hcmsgUHJlc2VudC5vZmYiDQogICAgKSAlPiUNCiAgICBkcGx5cjo6bXV0YXRlKHRpc3N1ZV90eXBlID0gIkhlYXJ0LWJ1bGJ1cyBhcnRlcmlvc3VzIikgJT4lDQogICAgdGlkeXI6OnVuaXRlKA0KICAgICAgY29sID0gInNpbGx5X3NvdXJjZSIsDQogICAgICBjKHNpbGx5LCBmaXNoX2lkKSwNCiAgICAgIHNlcCA9ICJfIiwNCiAgICAgIHJlbW92ZSA9IEZBTFNFDQogICAgKSAlPiUNCiAgICBkcGx5cjo6ZmlsdGVyKG9yaWdpbi5wYXIgPT0gIk5hdHVyYWwiKSAlPiUNCiAgICBkcGx5cjo6Z3JvdXBfYnkoc2V4KSAlPiUNCiAgICBkcGx5cjo6c2xpY2Vfc2FtcGxlKG4gPSAxOCwgcmVwbGFjZSA9IEZBTFNFKSAlPiUNCiAgICBkcGx5cjo6dW5ncm91cCgpICU+JSANCiAgICBkcGx5cjo6YXJyYW5nZShzaWxseSwgZmlzaF9pZCkgJT4lDQogICAgZHBseXI6OnNlbGVjdCgNCiAgICAgIHNpbGx5X3NvdXJjZSwNCiAgICAgIHNpbGx5LA0KICAgICAgZmlzaF9pZCwNCiAgICAgIGR3cF9iYXJjb2RlLA0KICAgICAgZHdwX3dlbGwsDQogICAgICB0aXNzdWVfdHlwZSwNCiAgICAgIHNhbXBsZV9kYXRlLA0KICAgICAgc2V4LA0KICAgICAgb3RvbGl0aF9tYXJrX3ByZXNlbnQNCiAgICApDQopDQoNCnN0b2NrZGFsZV8yMDE1X25hdHVyYWxfc2VsZWN0aW9uX05fZHlhZCAlPiUNCiAgZHBseXI6OmNvdW50KHNleCkNCmBgYA0KDQojIyMgRXh0cmFjdGlvbiBTZWxlY3Rpb24NCg0KQmluZCB0b2dldGhlciwgbWFrZSBzdXJlIG5vIGR1cGxpY2F0ZXMNCmBgYHtyfQ0KKA0KICBleHRyYWN0aW9uX1BTVE9DSzE1X25hdHVyYWwgPC0NCiAgICBkcGx5cjo6YmluZF9yb3dzKA0KICAgICAgc3RvY2tkYWxlXzIwMTVfbmF0dXJhbF9zZWxlY3Rpb25fTl9keWFkDQogICAgKSAlPiUNCiAgICBkcGx5cjo6YXJyYW5nZShzaWxseSwgZmlzaF9pZCkgJT4lIA0KICAgIGRwbHlyOjpkaXN0aW5jdCgpDQopDQpgYGANCg0KRG91YmxlIGNoZWNrIHNhbXBsZSBzaXplcw0KYGBge3J9DQpleHRyYWN0aW9uX1BTVE9DSzE1X25hdHVyYWwgJT4lIA0KICBkcGx5cjo6Y291bnQoc2lsbHkpDQoNCmV4dHJhY3Rpb25fUFNUT0NLMTVfbmF0dXJhbCAlPiUgDQogIGRwbHlyOjpjb3VudChzaWxseSwgc2V4KQ0KYGBgDQoNCldyaXRlIGl0IG91dCBmb3IgcG9zdGVyaXR5DQpgYGB7cn0NCnJlYWRyOjp3cml0ZV9jc3YoeCA9IGV4dHJhY3Rpb25fUFNUT0NLMTVfbmF0dXJhbCwgZmlsZSA9ICIuLi9vdXRwdXQvZXh0cmFjdGlvbl9QU1RPQ0sxNV9uYXR1cmFsLmNzdiIpDQpgYGANCg0KIyBIb2dhbiAyMDE2DQoNCk5lZWQgaGF0Y2hlcnkgc3RyYXlzIGFuZCBuYXR1cmFsLW9yaWdpbiBob21pbmcgZmlzaCAoaS5lLiB0aG9zZSB3aXRoIG5hdHVyYWwtb3JpZ2luIHBhcmVudHMpDQoNCiMjIE5hdHVyYWwtb3JpZ2luIEhvbWluZw0KDQpTcGxpdCBieSBzZXgsIHNhbXBsZWQgdGhyb3VnaG91dCB0aGUgc2Vhc29uDQoNCiMjIyBJbXBvcnQgRGF0YQ0KDQpCYWQgcHJhY3RpY2UsIGJ1dCBJJ20gZ29pbmcgdG8gZ3JhYiBvdXRwdXQgZGF0YSBmcm9tIFBXUy1QaW5rLVBhcmVudGFnZQ0KYGBge3J9DQooDQogIGFsbF9zdHJlYW1zX3BhcmVudHNfcGFpcmVkXzE0XzE2X2Nyb3NzIDwtDQogICAgcmVhZHI6OnJlYWRfY3N2KGZpbGUgPSAiLi4vLi4vUFdTIFBpbmsvR2l0SHViLVBXUy1QaW5rLVBhcmVudGFnZS9TdG9ja2RhbGVfSG9nYW5fR2lsbW91cl9QYWRkeV9FcmIvYWxsX3N0cmVhbXNfcGFyZW50c19wYWlyZWRfMTRfMTZfY3Jvc3MuY3N2IikNCikNCg0KKA0KICBhbGxfc3RyZWFtc19wYXJlbnRzX3BhaXJlZF8xNF8xNiA8LQ0KICAgIHJlYWRyOjpyZWFkX2NzdihmaWxlID0gIi4uLy4uL1BXUyBQaW5rL0dpdEh1Yi1QV1MtUGluay1QYXJlbnRhZ2UvU3RvY2tkYWxlX0hvZ2FuX0dpbG1vdXJfUGFkZHlfRXJiL2FsbF9zdHJlYW1zX3BhcmVudHNfcGFpcmVkXzE0XzE2LmNzdiIpDQopDQpgYGANCg0KIyMjIENob29zZSBmcm9tIE5OIGNyb3NzZXMNCg0KRmlsdGVyIGZvciBIb2dhbiBhbmQgb25seSANCmBgYHtyfQ0KaG9nYW5fMjAxNl9uYXR1cmFsX3NlbGVjdGlvbl9OTl9jcm9zcyA8LSBhbGxfc3RyZWFtc19wYXJlbnRzX3BhaXJlZF8xNF8xNl9jcm9zcyAlPiUgDQogIGRwbHlyOjpmaWx0ZXIoc3RyZWFtX29mZiA9PSBzdHJlYW1fc2lyZSwNCiAgICAgICAgICAgICAgICBzdHJlYW1fb2ZmID09ICJIb2dhbiIsDQogICAgICAgICAgICAgICAgb3JpZ2luX3NpcmUgPT0gb3JpZ2luX2RhbSwNCiAgICAgICAgICAgICAgICBvcmlnaW5fc2lyZSA9PSAiTmF0dXJhbCIpICU+JSANCiAgZHBseXI6Omdyb3VwX2J5KG1hdGluZ19pZCkgJT4lIA0KICBkcGx5cjo6c2xpY2Vfc2FtcGxlKG4gPSAxLCByZXBsYWNlID0gRkFMU0UpICU+JSANCiAgZHBseXI6Omdyb3VwX2J5KHBhcmVudF9pZF9zaXJlKSAlPiUgDQogIGRwbHlyOjpzbGljZV9zYW1wbGUobiA9IDEsIHJlcGxhY2UgPSBGQUxTRSkgJT4lIA0KICBkcGx5cjo6Z3JvdXBfYnkocGFyZW50X2lkX2RhbSkgJT4lIA0KICBkcGx5cjo6c2xpY2Vfc2FtcGxlKG4gPSAxLCByZXBsYWNlID0gRkFMU0UpICU+JSANCiAgZHBseXI6OnVuZ3JvdXAoKSANCg0KaG9nYW5fMjAxNl9uYXR1cmFsX3NlbGVjdGlvbl9OTl9jcm9zcyAlPiUgDQogIGRwbHlyOjpjb3VudChzZXhfb2ZmKQ0KYGBgDQoNClRoaXMgaXMgZHVtYiwgdmVyeSBmZXcgTk4gY3Jvc3NlcywganVzdCB1c2UgdGhlIGR5YWQgZGF0YS4NCg0KIyMjIENob3NlIGZyb20gTiBkeWFkcw0KDQpgYGB7cn0NCigNCiAgaG9nYW5fMjAxNl9uYXR1cmFsX3NlbGVjdGlvbl9OX2R5YWQgPC0NCiAgICBhbGxfc3RyZWFtc19wYXJlbnRzX3BhaXJlZF8xNF8xNiAlPiUNCiAgICBkcGx5cjo6cmVuYW1lKA0KICAgICAgc2lsbHkgPSBzaWxseV9vZmYsDQogICAgICBmaXNoX2lkID0gZmlzaF9pZF9vZmYsDQogICAgICBkd3BfYmFyY29kZSA9IGRuYV90cmF5X2NvZGVfb2ZmLA0KICAgICAgZHdwX3dlbGwgPSBkbmFfdHJheV93ZWxsX2NvZGVfb2ZmLA0KICAgICAgc2FtcGxlX2RhdGUgPSBkYXRlX29mZiwNCiAgICAgIHNleCA9IHNleF9vZmYsDQogICAgICBvdG9saXRoX21hcmtfcHJlc2VudCA9IG90b2xpdGhfbWFya19wcmVzZW50X29mZg0KICAgICkgJT4lDQogICAgZHBseXI6Om11dGF0ZSh0aXNzdWVfdHlwZSA9ICJIZWFydC1idWxidXMgYXJ0ZXJpb3N1cyIpICU+JQ0KICAgIHRpZHlyOjp1bml0ZSgNCiAgICAgIGNvbCA9ICJzaWxseV9zb3VyY2UiLA0KICAgICAgYyhzaWxseSwgZmlzaF9pZCksDQogICAgICBzZXAgPSAiXyIsDQogICAgICByZW1vdmUgPSBGQUxTRQ0KICAgICkgJT4lDQogICAgZHBseXI6OmZpbHRlcigNCiAgICAgIHN0cmVhbV9vZmYgPT0gc3RyZWFtX3BhciwNCiAgICAgIHN0cmVhbV9vZmYgPT0gIkhvZ2FuIiwNCiAgICAgIG9yaWdpbl9wYXIgPT0gIk5hdHVyYWwiLA0KICAgICAgISgNCiAgICAgICAgcGFyZW50X2lkICVpbiUgYWxsX3N0cmVhbXNfcGFyZW50c19wYWlyZWRfMTRfMTZfY3Jvc3MkcGFyZW50X2lkX2RhbQ0KICAgICAgKSwNCiAgICAgICEoDQogICAgICAgIHBhcmVudF9pZCAlaW4lIGFsbF9zdHJlYW1zX3BhcmVudHNfcGFpcmVkXzE0XzE2X2Nyb3NzJHBhcmVudF9pZF9zaXJlDQogICAgICApDQogICAgKSAlPiUNCiAgICBkcGx5cjo6Z3JvdXBfYnkoc2V4KSAlPiUNCiAgICBkcGx5cjo6c2xpY2Vfc2FtcGxlKG4gPSAxOCwgcmVwbGFjZSA9IEZBTFNFKSAlPiUNCiAgICBkcGx5cjo6dW5ncm91cCgpICU+JSANCiAgICBkcGx5cjo6YXJyYW5nZShzaWxseSwgZmlzaF9pZCkgJT4lDQogICAgZHBseXI6OnNlbGVjdCgNCiAgICAgIHNpbGx5X3NvdXJjZSwNCiAgICAgIHNpbGx5LA0KICAgICAgZmlzaF9pZCwNCiAgICAgIGR3cF9iYXJjb2RlLA0KICAgICAgZHdwX3dlbGwsDQogICAgICB0aXNzdWVfdHlwZSwNCiAgICAgIHNhbXBsZV9kYXRlLA0KICAgICAgc2V4LA0KICAgICAgb3RvbGl0aF9tYXJrX3ByZXNlbnQNCiAgICApDQopDQoNCmhvZ2FuXzIwMTZfbmF0dXJhbF9zZWxlY3Rpb25fTl9keWFkICU+JQ0KICBkcGx5cjo6Y291bnQoc2V4KQ0KYGBgDQoNCiMjIyBFeHRyYWN0aW9uIFNlbGVjdGlvbg0KDQpCaW5kIHRvZ2V0aGVyLCBtYWtlIHN1cmUgbm8gZHVwbGljYXRlcw0KYGBge3J9DQooDQogIGV4dHJhY3Rpb25fUEhPR0FOMTZfbmF0dXJhbCA8LQ0KICAgIGRwbHlyOjpiaW5kX3Jvd3MoDQogICAgICBob2dhbl8yMDE2X25hdHVyYWxfc2VsZWN0aW9uX05fZHlhZA0KICAgICkgJT4lDQogICAgZHBseXI6OmFycmFuZ2Uoc2lsbHksIGZpc2hfaWQpICU+JSANCiAgICBkcGx5cjo6ZGlzdGluY3QoKQ0KKQ0KYGBgDQoNCkRvdWJsZSBjaGVjayBzYW1wbGUgc2l6ZXMNCmBgYHtyfQ0KZXh0cmFjdGlvbl9QSE9HQU4xNl9uYXR1cmFsICU+JSANCiAgZHBseXI6OmNvdW50KHNpbGx5KQ0KDQpleHRyYWN0aW9uX1BIT0dBTjE2X25hdHVyYWwgJT4lIA0KICBkcGx5cjo6Y291bnQoc2lsbHksIHNleCkNCmBgYA0KDQpXcml0ZSBpdCBvdXQgZm9yIHBvc3Rlcml0eQ0KYGBge3J9DQpyZWFkcjo6d3JpdGVfY3N2KHggPSBleHRyYWN0aW9uX1BIT0dBTjE2X25hdHVyYWwsIGZpbGUgPSAiLi4vb3V0cHV0L2V4dHJhY3Rpb25fUEhPR0FOMTZfbmF0dXJhbC5jc3YiKQ0KYGBgDQoNCiMgSG9nYW4gMjAxNQ0KDQpOZWVkIGhhdGNoZXJ5IHN0cmF5cyBhbmQgbmF0dXJhbC1vcmlnaW4gaG9taW5nIGZpc2ggKGkuZS4gdGhvc2Ugd2l0aCBuYXR1cmFsLW9yaWdpbiBwYXJlbnRzKQ0KDQojIyBOYXR1cmFsLW9yaWdpbiBIb21pbmcNCg0KU3BsaXQgYnkgc2V4LCBzYW1wbGVkIHRocm91Z2hvdXQgdGhlIHNlYXNvbg0KDQojIyMgSW1wb3J0IERhdGENCg0KQmFkIHByYWN0aWNlLCBidXQgSSdtIGdvaW5nIHRvIGdyYWIgb3V0cHV0IGRhdGEgZnJvbSBQV1MtUGluay1QYXJlbnRhZ2UNCmBgYHtyfQ0KKA0KICBob2dhbl9wYXJlbnRzX3BhaXJlZF8xM18xNSA8LQ0KICAgIHJlYWRyOjpyZWFkX2NzdihmaWxlID0gIi4uLy4uL1BXUyBQaW5rL0dpdEh1Yi1QV1MtUGluay1QYXJlbnRhZ2UvSG9nYW4vaG9nYW5fcGFyZW50c19wYWlyZWRfMTNfMTUuY3N2IikNCikNCmBgYA0KDQojIyMgQ2hvb3NlIGZyb20gTk4gY3Jvc3Nlcw0KDQpUaGVyZSBhcmUgaXMgbm8gdHJpYWQgZGF0YSBmb3IgdGhlIDIwMTMvMjAxNSBwZWRpZ3JlZXMNCg0KIyMjIENob3NlIGZyb20gTiBkeWFkcw0KDQpgYGB7cn0NCigNCiAgaG9nYW5fMjAxNV9uYXR1cmFsX3NlbGVjdGlvbl9OX2R5YWQgPC0NCiAgICBob2dhbl9wYXJlbnRzX3BhaXJlZF8xM18xNSAlPiUNCiAgICBkcGx5cjo6cmVuYW1lKA0KICAgICAgc2lsbHkgPSBTSUxMWS5vZmYsDQogICAgICBmaXNoX2lkID0gIkZpc2ggSUQub2ZmIiwNCiAgICAgIGR3cF9iYXJjb2RlID0gIkROQSBUcmF5IENvZGUub2ZmIiwNCiAgICAgIGR3cF93ZWxsID0gIkROQSBUcmF5IFdlbGwgQ29kZS5vZmYiLA0KICAgICAgc2FtcGxlX2RhdGUgPSBkYXRlLm9mZiwNCiAgICAgIHNleCA9IFNFWC5vZmYsDQogICAgICBvdG9saXRoX21hcmtfcHJlc2VudCA9ICJPdG9saXRoIE1hcmsgUHJlc2VudC5vZmYiDQogICAgKSAlPiUNCiAgICBkcGx5cjo6bXV0YXRlKHRpc3N1ZV90eXBlID0gIkhlYXJ0LWJ1bGJ1cyBhcnRlcmlvc3VzIikgJT4lDQogICAgdGlkeXI6OnVuaXRlKA0KICAgICAgY29sID0gInNpbGx5X3NvdXJjZSIsDQogICAgICBjKHNpbGx5LCBmaXNoX2lkKSwNCiAgICAgIHNlcCA9ICJfIiwNCiAgICAgIHJlbW92ZSA9IEZBTFNFDQogICAgKSAlPiUNCiAgICBkcGx5cjo6ZmlsdGVyKG9yaWdpbi5wYXIgPT0gIk5hdHVyYWwiKSAlPiUNCiAgICBkcGx5cjo6Z3JvdXBfYnkoc2V4KSAlPiUNCiAgICBkcGx5cjo6c2xpY2Vfc2FtcGxlKG4gPSAxOCwgcmVwbGFjZSA9IEZBTFNFKSAlPiUNCiAgICBkcGx5cjo6dW5ncm91cCgpICU+JSANCiAgICBkcGx5cjo6YXJyYW5nZShzaWxseSwgZmlzaF9pZCkgJT4lDQogICAgZHBseXI6OnNlbGVjdCgNCiAgICAgIHNpbGx5X3NvdXJjZSwNCiAgICAgIHNpbGx5LA0KICAgICAgZmlzaF9pZCwNCiAgICAgIGR3cF9iYXJjb2RlLA0KICAgICAgZHdwX3dlbGwsDQogICAgICB0aXNzdWVfdHlwZSwNCiAgICAgIHNhbXBsZV9kYXRlLA0KICAgICAgc2V4LA0KICAgICAgb3RvbGl0aF9tYXJrX3ByZXNlbnQNCiAgICApDQopDQoNCmhvZ2FuXzIwMTVfbmF0dXJhbF9zZWxlY3Rpb25fTl9keWFkICU+JQ0KICBkcGx5cjo6Y291bnQoc2V4KQ0KYGBgDQoNCiMjIyBFeHRyYWN0aW9uIFNlbGVjdGlvbg0KDQpCaW5kIHRvZ2V0aGVyLCBtYWtlIHN1cmUgbm8gZHVwbGljYXRlcw0KYGBge3J9DQooDQogIGV4dHJhY3Rpb25fUEhPR0FOMTVfbmF0dXJhbCA8LQ0KICAgIGRwbHlyOjpiaW5kX3Jvd3MoDQogICAgICBob2dhbl8yMDE1X25hdHVyYWxfc2VsZWN0aW9uX05fZHlhZA0KICAgICkgJT4lDQogICAgZHBseXI6OmFycmFuZ2Uoc2lsbHksIGZpc2hfaWQpICU+JSANCiAgICBkcGx5cjo6ZGlzdGluY3QoKQ0KKQ0KYGBgDQoNCkRvdWJsZSBjaGVjayBzYW1wbGUgc2l6ZXMNCmBgYHtyfQ0KZXh0cmFjdGlvbl9QSE9HQU4xNV9uYXR1cmFsICU+JSANCiAgZHBseXI6OmNvdW50KHNpbGx5KQ0KDQpleHRyYWN0aW9uX1BIT0dBTjE1X25hdHVyYWwgJT4lIA0KICBkcGx5cjo6Y291bnQoc2lsbHksIHNleCkNCmBgYA0KDQpXcml0ZSBpdCBvdXQgZm9yIHBvc3Rlcml0eQ0KYGBge3J9DQpyZWFkcjo6d3JpdGVfY3N2KHggPSBleHRyYWN0aW9uX1BIT0dBTjE1X25hdHVyYWwsIGZpbGUgPSAiLi4vb3V0cHV0L2V4dHJhY3Rpb25fUEhPR0FOMTVfbmF0dXJhbC5jc3YiKQ0KYGBgDQoNCiMgSGF0Y2hlcnktb3JpZ2luIHN0cmF5aW5nDQoNCkZvciBTdG9ja2RhbGUgYW5kIEhvZ2FuIDIwMTUgYW5kIDIwMTYNClNwbGl0IGJ5IHNleCBhbmQgaGF0Y2hlcnkgKG9ubHkgQUZLIGFuZCBXSE4sIG5vIGJyb29kc291cmNlIGZvciBDQ0ggYW5kIHRvbyBmZXcgVkZEQSkNClJhbmRvbSB3aXRoIHJlc3BlY3QgdG8gc2FtcGxlIGxvY2F0aW9uIGFuZCBzYW1wbGUgZGF0ZQ0KDQojIyBJbXBvcnQgRGF0YQ0KDQojIyMgU2FsbW9uIEJpb2xvZ2ljYWwgRGF0YQ0KDQpPdG9saXRoIHJlYWQgZGF0YSBsaXZlcyBoZXJlLi4uDQpgYGB7cn0NCigNCiAgb2NlYW5ha19oYXRjaGVyeV9vZyA8LQ0KICAgIHJlYWRyOjpyZWFkX2NzdihmaWxlID0gIi4uL2RhdGEvU3RvY2tkYWxlIDIwMTUtMjAxNiBIb2dhbiAyMDE1LTIwMTYgU3ByaW5nIDIwMTQtMjAxNSBBSFJQIFNhbG1vbiBCaW9sb2dpY2FsIERhdGEgMjAyMjAzMjJfMTE1NjA4LmNzdiIpDQopDQpgYGANCg0KTW9kaWZ5LCBmaWx0ZXIgZm9yIHNpbGx5IGNvZGVzIG9mIGludGVyZXN0IGFuZCB0aXNzdWUgdHlwZSAiT3RvbGl0aCIsIGFuZCBvbmx5IEFGSyBhbmQgV05IIGluZGl2aWR1YWxzDQpgYGB7cn0NCigNCiAgb2NlYW5ha19oYXRjaGVyeSA8LSBvY2VhbmFrX2hhdGNoZXJ5X29nICU+JQ0KICAgIGRwbHlyOjpmaWx0ZXIoDQogICAgICBTSUxMWV9DT0RFICVpbiUgYygiUFNUT0NLMTYiLCAiUFNUT0NLMTUiLCAiUEhPR0FOMTYiLCAiUEhPR0FOMTUiKSwNCiAgICAgIFRJU1NVRV9UWVBFID09ICJIZWFydC1idWxidXMgYXJ0ZXJpb3N1cyIsDQogICAgICBPVE9MSVRIX01BUktfUFJFU0VOVCA9PSAiWUVTIiwNCiAgICAgIFNFWCAhPSAiVSINCiAgICApICU+JQ0KICAgIGRwbHlyOjpyZW5hbWUoDQogICAgICBzaWxseSA9IFNJTExZX0NPREUsDQogICAgICBmaXNoX2lkID0gRklTSF9JRCwNCiAgICAgIHRpc3N1ZV90eXBlID0gVElTU1VFX1RZUEUsDQogICAgICBkd3BfYmFyY29kZSA9IEROQV9UUkFZX0NPREUsDQogICAgICBkd3Bfd2VsbCA9IEROQV9UUkFZX1dFTExfQ09ERSwNCiAgICAgIHNhbXBsZV9kYXRlID0gU0FNUExFX0RBVEUsDQogICAgICBzZXggPSBTRVgsDQogICAgICBvdG9saXRoX21hcmtfcHJlc2VudCA9IE9UT0xJVEhfTUFSS19QUkVTRU5ULA0KICAgICAgb3RvbGl0aF9tYXJrX2lkID0gT1RPTElUSF9NQVJLX0lEDQogICAgKSAlPiUNCiAgICBkcGx5cjo6bXV0YXRlKA0KICAgICAgc2FtcGxlX2RhdGUgPSBsdWJyaWRhdGU6OnltZChzYW1wbGVfZGF0ZSksDQogICAgICBoYXRjaGVyeSA9IHN0cmluZ3I6OnN0cl9zdWIoDQogICAgICAgIHN0cmluZyA9IG90b2xpdGhfbWFya19pZCwNCiAgICAgICAgc3RhcnQgPSAxLA0KICAgICAgICBlbmQgPSAzDQogICAgICApDQogICAgKSAlPiUNCiAgICBkcGx5cjo6ZmlsdGVyKGhhdGNoZXJ5ICVpbiUgYygiQUZLIiwgIldOSCIpKSAlPiUgDQogICAgdGlkeXI6OnVuaXRlKA0KICAgICAgY29sID0gInNpbGx5X3NvdXJjZSIsDQogICAgICBjKHNpbGx5LCBmaXNoX2lkKSwNCiAgICAgIHNlcCA9ICJfIiwNCiAgICAgIHJlbW92ZSA9IEZBTFNFDQogICAgKSAlPiUNCiAgICBkcGx5cjo6c2VsZWN0KA0KICAgICAgc2lsbHlfc291cmNlLA0KICAgICAgc2lsbHksDQogICAgICBmaXNoX2lkLA0KICAgICAgZHdwX2JhcmNvZGUsDQogICAgICBkd3Bfd2VsbCwNCiAgICAgIHRpc3N1ZV90eXBlLA0KICAgICAgc2FtcGxlX2RhdGUsDQogICAgICBzZXgsDQogICAgICBoYXRjaGVyeSwNCiAgICAgIG90b2xpdGhfbWFya19wcmVzZW50LA0KICAgICAgb3RvbGl0aF9tYXJrX2lkDQogICAgKQ0KKQ0KYGBgDQoNCkhvdyBtYW55Pw0KYGBge3J9DQpvY2VhbmFrX2hhdGNoZXJ5ICU+JSANCiAgZHBseXI6OmNvdW50KHNpbGx5LCBzZXgsIGhhdGNoZXJ5KQ0KYGBgDQoNCiMjIEV4dHJhY3Rpb24gU2VsZWN0aW9uDQoNCkZyb20gZWFjaCBzaWxseSwgZ3JhYiB0aGUgZmlyc3QgMTggZmlzaCBmcm9tIGVhY2ggc2V4IHRoYXQgYXJlIG5vdCBvdG9saXRoIG1hcmtlZCAoaS5lLiBuYXR1cmFsLW9yaWdpbiBmaXNoKS4gVG90YWwgb2YgMzYgZmlzaCBwZXIgc2lsbHksIDM2IGZpc2ggcGVyIHNhbXBsaW5nIHVuaXQuDQpgYGB7cn0NCigNCiAgZXh0cmFjdGlvbl9oYXRjaGVyeV9zdHJheSA8LSBvY2VhbmFrX2hhdGNoZXJ5ICU+JQ0KICAgIGRwbHlyOjpmaWx0ZXIob3RvbGl0aF9tYXJrX3ByZXNlbnQgPT0gIllFUyIsDQogICAgICAgICAgICAgICAgICBzZXggIT0gIlUiKSAlPiUNCiAgICBkcGx5cjo6Z3JvdXBfYnkoc2lsbHksIHNleCwgaGF0Y2hlcnkpICU+JQ0KICAgIGRwbHlyOjpzbGljZV9zYW1wbGUobiA9IDksIHJlcGxhY2UgPSBGQUxTRSkgJT4lDQogICAgZHBseXI6OnVuZ3JvdXAoKSAlPiUgDQogICAgZHBseXI6OmFycmFuZ2Uoc2lsbHksIGZpc2hfaWQpICU+JSANCiAgICBkcGx5cjo6c2VsZWN0KA0KICAgICAgc2lsbHlfc291cmNlLA0KICAgICAgc2lsbHksDQogICAgICBmaXNoX2lkLA0KICAgICAgZHdwX2JhcmNvZGUsDQogICAgICBkd3Bfd2VsbCwNCiAgICAgIHRpc3N1ZV90eXBlLA0KICAgICAgc2FtcGxlX2RhdGUsDQogICAgICBzZXgsDQogICAgICBoYXRjaGVyeSwNCiAgICAgIG90b2xpdGhfbWFya19wcmVzZW50LA0KICAgICAgb3RvbGl0aF9tYXJrX2lkDQogICAgKQ0KKQ0KYGBgDQoNCkRvdWJsZSBjaGVjaw0KYGBge3J9DQpleHRyYWN0aW9uX2hhdGNoZXJ5X3N0cmF5ICU+JSANCiAgZHBseXI6OmNvdW50KHNpbGx5LCBzZXgsIGhhdGNoZXJ5KQ0KYGBgDQoNCk1pc3NpbmcgNyBmZW1hbGVzIGFuZCA4IG1hbGVzIGZyb20gUFNUT0NLMTYsIFdOSC4gV2lsbCByZXBsYWNlIHdpdGggQUZLIGZpc2guDQpgYGB7cn0NCigNCiAgZXh0cmFjdGlvbl9oYXRjaGVyeV9zdHJheV9QU1RPQ0sxNl9BRktfZmVtYWxlIDwtIG9jZWFuYWtfaGF0Y2hlcnkgJT4lDQogICAgZHBseXI6OmZpbHRlcihzaWxseSA9PSAiUFNUT0NLMTYiLA0KICAgICAgICAgICAgICAgICAgc2V4ID09ICJGIiwNCiAgICAgICAgICAgICAgICAgIGhhdGNoZXJ5ID09ICJBRksiKSAlPiUNCiAgICBkcGx5cjo6Z3JvdXBfYnkoc2lsbHksIHNleCwgaGF0Y2hlcnkpICU+JQ0KICAgIGRwbHlyOjpzbGljZV9zYW1wbGUobiA9IDcsIHJlcGxhY2UgPSBGQUxTRSkgJT4lDQogICAgZHBseXI6OnVuZ3JvdXAoKSAlPiUgDQogICAgZHBseXI6OmFycmFuZ2Uoc2lsbHksIGZpc2hfaWQpICU+JSANCiAgICBkcGx5cjo6c2VsZWN0KA0KICAgICAgc2lsbHlfc291cmNlLA0KICAgICAgc2lsbHksDQogICAgICBmaXNoX2lkLA0KICAgICAgZHdwX2JhcmNvZGUsDQogICAgICBkd3Bfd2VsbCwNCiAgICAgIHRpc3N1ZV90eXBlLA0KICAgICAgc2FtcGxlX2RhdGUsDQogICAgICBzZXgsDQogICAgICBoYXRjaGVyeSwNCiAgICAgIG90b2xpdGhfbWFya19wcmVzZW50LA0KICAgICAgb3RvbGl0aF9tYXJrX2lkDQogICAgKQ0KKQ0KDQooDQogIGV4dHJhY3Rpb25faGF0Y2hlcnlfc3RyYXlfUFNUT0NLMTZfQUZLX21hbGUgPC0gb2NlYW5ha19oYXRjaGVyeSAlPiUNCiAgICBkcGx5cjo6ZmlsdGVyKHNpbGx5ID09ICJQU1RPQ0sxNiIsDQogICAgICAgICAgICAgICAgICBzZXggPT0gIk0iLA0KICAgICAgICAgICAgICAgICAgaGF0Y2hlcnkgPT0gIkFGSyIpICU+JQ0KICAgIGRwbHlyOjpncm91cF9ieShzaWxseSwgc2V4LCBoYXRjaGVyeSkgJT4lDQogICAgZHBseXI6OnNsaWNlX3NhbXBsZShuID0gOCwgcmVwbGFjZSA9IEZBTFNFKSAlPiUNCiAgICBkcGx5cjo6dW5ncm91cCgpICU+JSANCiAgICBkcGx5cjo6YXJyYW5nZShzaWxseSwgZmlzaF9pZCkgJT4lIA0KICAgIGRwbHlyOjpzZWxlY3QoDQogICAgICBzaWxseV9zb3VyY2UsDQogICAgICBzaWxseSwNCiAgICAgIGZpc2hfaWQsDQogICAgICBkd3BfYmFyY29kZSwNCiAgICAgIGR3cF93ZWxsLA0KICAgICAgdGlzc3VlX3R5cGUsDQogICAgICBzYW1wbGVfZGF0ZSwNCiAgICAgIHNleCwNCiAgICAgIGhhdGNoZXJ5LA0KICAgICAgb3RvbGl0aF9tYXJrX3ByZXNlbnQsDQogICAgICBvdG9saXRoX21hcmtfaWQNCiAgICApDQopDQpgYGANCg0KQmluZCB0b2dldGhlciwgbWFrZSBzdXJlIG5vIGR1cGxpY2F0ZXMNCmBgYHtyfQ0KKA0KICBleHRyYWN0aW9uX2hhdGNoZXJ5X3N0cmF5X2ZpbmFsIDwtDQogICAgZHBseXI6OmJpbmRfcm93cygNCiAgICAgIGV4dHJhY3Rpb25faGF0Y2hlcnlfc3RyYXksDQogICAgICBleHRyYWN0aW9uX2hhdGNoZXJ5X3N0cmF5X1BTVE9DSzE2X0FGS19mZW1hbGUsDQogICAgICBleHRyYWN0aW9uX2hhdGNoZXJ5X3N0cmF5X1BTVE9DSzE2X0FGS19tYWxlDQogICAgKSAlPiUNCiAgICBkcGx5cjo6ZGlzdGluY3QoKQ0KKQ0KYGBgDQoNCkRvdWJsZSBjaGVjayBzYW1wbGUgc2l6ZXMNCmBgYHtyfQ0KZXh0cmFjdGlvbl9oYXRjaGVyeV9zdHJheV9maW5hbCAlPiUgDQogIGRwbHlyOjpjb3VudChzaWxseSkNCg0KZXh0cmFjdGlvbl9oYXRjaGVyeV9zdHJheV9maW5hbCAlPiUgDQogIGRwbHlyOjpjb3VudChzaWxseSwgc2V4KQ0KDQpleHRyYWN0aW9uX2hhdGNoZXJ5X3N0cmF5X2ZpbmFsICU+JSANCiAgZHBseXI6OmNvdW50KHNpbGx5LCBzZXgsIGhhdGNoZXJ5KQ0KYGBgDQoNCldyaXRlIGl0IG91dCBmb3IgcG9zdGVyaXR5DQpgYGB7cn0NCnJlYWRyOjp3cml0ZV9jc3YoeCA9IGV4dHJhY3Rpb25faGF0Y2hlcnlfc3RyYXlfZmluYWwsIGZpbGUgPSAiLi4vb3V0cHV0L2V4dHJhY3Rpb25fc2VsZWN0aW9uX2hhdGNoZXJ5X3N0cmF5LmNzdiIpDQpgYGANCg0KIyBXaWxkIFN5c3RlbXMgLSBObyBTdHJheXMNCg0KU3ByaW5nIENyZWVrIQ0KU3BsaXQgYnkgc2V4LCBzYW1wbGVkIHRocm91Z2hvdXQgdGhlIHNlYXNvbg0KDQojIyBJbXBvcnQgRGF0YQ0KDQojIyMgU2FsbW9uIEJpb2xvZ2ljYWwgRGF0YQ0KDQpPdG9saXRoIHJlYWQgZGF0YSBsaXZlcyBoZXJlLi4uDQpgYGB7cn0NCigNCiAgb2NlYW5ha19zcHJpbmdfb2cgPC0NCiAgICByZWFkcjo6cmVhZF9jc3YoZmlsZSA9ICIuLi9kYXRhL1NwcmluZyAyMDE0LTIwMTUgQUhSUCBTYWxtb24gQmlvbG9naWNhbCBEYXRhIDIwMjIwMzIyXzEyMjUzOC5jc3YiKQ0KKQ0KYGBgDQoNCk1vZGlmeSwgZmlsdGVyIGZvciBzaWxseSBjb2RlcyBvZiBpbnRlcmVzdCBhbmQgdGlzc3VlIHR5cGUgIk90b2xpdGgiDQpgYGB7cn0NCigNCiAgb2NlYW5ha19zcHJpbmcgPC0gb2NlYW5ha19zcHJpbmdfb2cgJT4lDQogICAgZHBseXI6OmZpbHRlcigNCiAgICAgIFNJTExZX0NPREUgJWluJSBjKCJQU1BSSU4xNCIsICJQU1BSSU4xNSIpLA0KICAgICAgVElTU1VFX1RZUEUgPT0gIkhlYXJ0LWJ1bGJ1cyBhcnRlcmlvc3VzIiwNCiAgICAgIE9UT0xJVEhfTUFSS19QUkVTRU5UID09ICJOTyIsDQogICAgICBTRVggIT0gIlUiDQogICAgKSAlPiUNCiAgICBkcGx5cjo6cmVuYW1lKA0KICAgICAgc2lsbHkgPSBTSUxMWV9DT0RFLA0KICAgICAgZmlzaF9pZCA9IEZJU0hfSUQsDQogICAgICB0aXNzdWVfdHlwZSA9IFRJU1NVRV9UWVBFLA0KICAgICAgZHdwX2JhcmNvZGUgPSBETkFfVFJBWV9DT0RFLA0KICAgICAgZHdwX3dlbGwgPSBETkFfVFJBWV9XRUxMX0NPREUsDQogICAgICBzYW1wbGVfZGF0ZSA9IFNBTVBMRV9EQVRFLA0KICAgICAgc2V4ID0gU0VYLA0KICAgICAgb3RvbGl0aF9tYXJrX3ByZXNlbnQgPSBPVE9MSVRIX01BUktfUFJFU0VOVA0KICAgICkgJT4lDQogICAgZHBseXI6Om11dGF0ZSgNCiAgICAgIHNhbXBsZV9kYXRlID0gbHVicmlkYXRlOjp5bWQoc2FtcGxlX2RhdGUpDQogICAgKSAlPiUNCiAgICB0aWR5cjo6dW5pdGUoDQogICAgICBjb2wgPSAic2lsbHlfc291cmNlIiwNCiAgICAgIGMoc2lsbHksIGZpc2hfaWQpLA0KICAgICAgc2VwID0gIl8iLA0KICAgICAgcmVtb3ZlID0gRkFMU0UNCiAgICApICU+JQ0KICAgIGRwbHlyOjpzZWxlY3QoDQogICAgICBzaWxseV9zb3VyY2UsDQogICAgICBzaWxseSwNCiAgICAgIGZpc2hfaWQsDQogICAgICBkd3BfYmFyY29kZSwNCiAgICAgIGR3cF93ZWxsLA0KICAgICAgdGlzc3VlX3R5cGUsDQogICAgICBzYW1wbGVfZGF0ZSwNCiAgICAgIHNleCwNCiAgICAgIG90b2xpdGhfbWFya19wcmVzZW50DQogICAgKQ0KKQ0KYGBgDQoNCiMjIEV4dHJhY3Rpb24gU2VsZWN0aW9uDQoNCkZyb20gZWFjaCBzaWxseSwgZ3JhYiB0aGUgZmlyc3QgMTggZmlzaCBmcm9tIGVhY2ggc2V4IHRoYXQgYXJlIG5vdCBvdG9saXRoIG1hcmtlZCAoaS5lLiBuYXR1cmFsLW9yaWdpbiBmaXNoKS4gVG90YWwgb2YgMzYgZmlzaCBwZXIgc2lsbHksIDM2IGZpc2ggcGVyIHNhbXBsaW5nIHVuaXQuDQpgYGB7cn0NCigNCiAgZXh0cmFjdGlvbl9zcHJpbmcgPC0gb2NlYW5ha19zcHJpbmcgJT4lDQogICAgZHBseXI6OmZpbHRlcihvdG9saXRoX21hcmtfcHJlc2VudCA9PSAiTk8iLA0KICAgICAgICAgICAgICAgICAgc2V4ICE9ICJVIikgJT4lDQogICAgZHBseXI6Omdyb3VwX2J5KHNpbGx5LCBzZXgpICU+JQ0KICAgIGRwbHlyOjpzbGljZV9zYW1wbGUobiA9IDE4LCByZXBsYWNlID0gRkFMU0UpICU+JQ0KICAgIGRwbHlyOjp1bmdyb3VwKCkgJT4lIA0KICAgIGRwbHlyOjphcnJhbmdlKHNpbGx5LCBmaXNoX2lkKSAlPiUgDQogICAgZHBseXI6OnNlbGVjdCgNCiAgICAgIHNpbGx5X3NvdXJjZSwNCiAgICAgIHNpbGx5LA0KICAgICAgZmlzaF9pZCwNCiAgICAgIGR3cF9iYXJjb2RlLA0KICAgICAgZHdwX3dlbGwsDQogICAgICB0aXNzdWVfdHlwZSwNCiAgICAgIHNhbXBsZV9kYXRlLA0KICAgICAgc2V4LA0KICAgICAgb3RvbGl0aF9tYXJrX3ByZXNlbnQNCiAgICApDQopDQpgYGANCg0KRG91YmxlIGNoZWNrDQpgYGB7cn0NCmV4dHJhY3Rpb25fc3ByaW5nICU+JSANCiAgZHBseXI6OmNvdW50KHNpbGx5LCBzZXgsIG90b2xpdGhfbWFya19wcmVzZW50KQ0KYGBgDQoNCldyaXRlIGl0IG91dCBmb3IgcG9zdGVyaXR5DQpgYGB7cn0NCnJlYWRyOjp3cml0ZV9jc3YoeCA9IGV4dHJhY3Rpb25fc3ByaW5nLCBmaWxlID0gIi4uL291dHB1dC9leHRyYWN0aW9uX3NlbGVjdGlvbl9QU1BSSU4xNF9QU1BSSU4xNS5jc3YiKQ0KYGBgDQoNCiMjIEV4dHJhY3Rpb24gU2VsZWN0aW9uIHRha2UgMiAtIDMvMzEvMjINCg0KRXJpbiBub3RlZCB0aGF0IHNldmVyYWwgZmlzaCB3ZXJlIG1pc3NpbmcgZnJvbSBQU1BSSU4xNC4NCg0KRmlyc3QsIGxldCdzIHJlYWQgaW4gd2hhdCB3ZSBoYWQgYXNrZWQgZm9yIHNvIHdlIGNhbiBhdm9pZCB0aG9zZS4NCmBgYHtyfQ0KKGV4dHJhY3Rpb25fc3ByaW5nIDwtIHJlYWRyOjpyZWFkX2NzdihmaWxlID0gIi4uL291dHB1dC9leHRyYWN0aW9uX3NlbGVjdGlvbl9QU1BSSU4xNF9QU1BSSU4xNS5jc3YiKSkNCmBgYA0KDQpIZXJlIGFyZSB0aGUgc2FtcGxlIG51bWJlcnMgdGhhdCBFcmluIG5vdGVkIHdlcmUgbWlzc2luZywgc28gd2Uga25vdyB3aGF0IHdlIG5lZWQgdG8gcmVwbGFjZS4NCmBgYHtyfQ0KZXh0cmFjdGlvbl9zcHJpbmdfbWlzc2luZ19maXNoX2lkcyA8LSBjKDUxLCA1NCwgNTUsIDk5LCAxMDEsIDEwMywgMTcyLCAyMjUsIDIzMSwgMjM2LCAyMzcsIDIzOCkNCmBgYA0KDQpXaGljaCBzZXg/DQpgYGB7cn0NCmV4dHJhY3Rpb25fc3ByaW5nICU+JSANCiAgZHBseXI6OmZpbHRlcihzaWxseSA9PSAiUFNQUklOMTQiLA0KICAgICAgICAgICAgICAgIGZpc2hfaWQgJWluJSBleHRyYWN0aW9uX3NwcmluZ19taXNzaW5nX2Zpc2hfaWRzKSAlPiUgDQogIGRwbHlyOjpjb3VudChzaWxseSwgc2V4LCBvdG9saXRoX21hcmtfcHJlc2VudCkNCmBgYA0KDQpMb29rcyBsaWtlIHdlIG5lZWQgdG8gcmVwbGFjZSA2IGZpc2ggZnJvbSBlYWNoIHNleC4NCmBgYHtyfQ0KKA0KICBleHRyYWN0aW9uX3NwcmluZ192MiA8LSBvY2VhbmFrX3NwcmluZyAlPiUNCiAgICBkcGx5cjo6ZmlsdGVyKCFzaWxseV9zb3VyY2UgJWluJSBleHRyYWN0aW9uX3NwcmluZyRzaWxseV9zb3VyY2UsDQogICAgICAgICAgICAgICAgICBzaWxseSA9PSAiUFNQUklOMTQiLA0KICAgICAgICAgICAgICAgICAgb3RvbGl0aF9tYXJrX3ByZXNlbnQgPT0gIk5PIiwNCiAgICAgICAgICAgICAgICAgIHNleCAhPSAiVSIpICU+JQ0KICAgIGRwbHlyOjpncm91cF9ieShzaWxseSwgc2V4KSAlPiUNCiAgICBkcGx5cjo6c2xpY2Vfc2FtcGxlKG4gPSA2LCByZXBsYWNlID0gRkFMU0UpICU+JQ0KICAgIGRwbHlyOjp1bmdyb3VwKCkgJT4lIA0KICAgIGRwbHlyOjphcnJhbmdlKHNpbGx5LCBmaXNoX2lkKSAlPiUgDQogICAgZHBseXI6OnNlbGVjdCgNCiAgICAgIHNpbGx5X3NvdXJjZSwNCiAgICAgIHNpbGx5LA0KICAgICAgZmlzaF9pZCwNCiAgICAgIGR3cF9iYXJjb2RlLA0KICAgICAgZHdwX3dlbGwsDQogICAgICB0aXNzdWVfdHlwZSwNCiAgICAgIHNhbXBsZV9kYXRlLA0KICAgICAgc2V4LA0KICAgICAgb3RvbGl0aF9tYXJrX3ByZXNlbnQNCiAgICApDQopDQpgYGANCg0KRG91YmxlIGNoZWNrDQpgYGB7cn0NCmV4dHJhY3Rpb25fc3ByaW5nX3YyICU+JSANCiAgZHBseXI6OmNvdW50KHNpbGx5LCBzZXgsIG90b2xpdGhfbWFya19wcmVzZW50KQ0KYGBgDQoNCldyaXRlIGl0IG91dCBmb3IgcG9zdGVyaXR5DQpgYGB7cn0NCnJlYWRyOjp3cml0ZV9jc3YoeCA9IGV4dHJhY3Rpb25fc3ByaW5nX3YyLCBmaWxlID0gIi4uL291dHB1dC9leHRyYWN0aW9uX3NlbGVjdGlvbl9QU1BSSU4xNF92Mi5jc3YiKQ0KYGBgDQoNCkVuZC4uLg==